diff --git a/java/java-frontback-psi-api/src/com/intellij/psi/LanguageLevelKey.kt b/java/java-frontback-psi-api/src/com/intellij/psi/LanguageLevelKey.kt new file mode 100644 index 000000000000..b806529db9fe --- /dev/null +++ b/java/java-frontback-psi-api/src/com/intellij/psi/LanguageLevelKey.kt @@ -0,0 +1,12 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.psi + +import com.intellij.openapi.util.Key +import com.intellij.pom.java.LanguageLevel +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +object LanguageLevelKey { + @JvmField + val FILE_LANGUAGE_LEVEL_KEY: Key = Key.create("FORCE_LANGUAGE_LEVEL") +} \ No newline at end of file diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java index 5f0c24452829..dac407015efc 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java @@ -1081,7 +1081,7 @@ public final class PsiUtil extends PsiUtilCore { return false; } - public static final Key FILE_LANGUAGE_LEVEL_KEY = LanguageLevel.FILE_LANGUAGE_LEVEL_KEY; + public static final Key FILE_LANGUAGE_LEVEL_KEY = LanguageLevelKey.FILE_LANGUAGE_LEVEL_KEY; public static boolean isLanguageLevel5OrHigher(@NotNull PsiElement element) { return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_5); diff --git a/java/java-syntax/src/com/intellij/openapi/projectRoots/JavaSdkVersion.kt b/java/java-syntax/src/com/intellij/openapi/projectRoots/JavaSdkVersion.kt index bf457e93cca9..8526554f31ca 100644 --- a/java/java-syntax/src/com/intellij/openapi/projectRoots/JavaSdkVersion.kt +++ b/java/java-syntax/src/com/intellij/openapi/projectRoots/JavaSdkVersion.kt @@ -1,19 +1,16 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.openapi.projectRoots; +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.openapi.projectRoots -import com.intellij.openapi.util.NlsSafe; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.util.lang.JavaVersion; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; +import com.intellij.openapi.util.NlsSafe +import com.intellij.pom.java.LanguageLevel +import com.intellij.util.lang.JavaVersion +import com.intellij.util.lang.JavaVersion.Companion.tryParse /** - * Represents a version of Java SDK. Use {@code JavaSdk#getVersion(Sdk)} method to obtain a version of an {@code Sdk}. + * Represents a version of Java SDK. Use `JavaSdk#getVersion(Sdk)` method to obtain a version of an `Sdk`. * @see LanguageLevel */ -public enum JavaSdkVersion { +enum class JavaSdkVersion(val maxLanguageLevel: LanguageLevel) { JDK_1_0(LanguageLevel.JDK_1_3), JDK_1_1(LanguageLevel.JDK_1_3), JDK_1_2(LanguageLevel.JDK_1_3), @@ -41,45 +38,42 @@ public enum JavaSdkVersion { JDK_24(LanguageLevel.JDK_24), JDK_25(LanguageLevel.JDK_X); - private final LanguageLevel myMaxLanguageLevel; - - JavaSdkVersion(@NotNull LanguageLevel maxLanguageLevel) { - myMaxLanguageLevel = maxLanguageLevel; - } - - public @NotNull LanguageLevel getMaxLanguageLevel() { - return myMaxLanguageLevel; - } - - public @NotNull @NlsSafe String getDescription() { - int feature = ordinal(); - return feature < 5 ? "1." + feature : String.valueOf(feature); - } - - public boolean isAtLeast(@NotNull JavaSdkVersion version) { - return compareTo(version) >= 0; - } - - public static @NotNull JavaSdkVersion fromLanguageLevel(@NotNull LanguageLevel languageLevel) throws IllegalArgumentException { - JavaSdkVersion[] values = values(); - if (languageLevel == LanguageLevel.JDK_X) { - return values[values.length - 1]; + val description: @NlsSafe String + get() { + val feature = ordinal + return if (feature < 5) "1.$feature" else feature.toString() } - int feature = languageLevel.feature(); - if (feature < values.length) { - return values[feature]; + + fun isAtLeast(version: JavaSdkVersion): Boolean { + return compareTo(version) >= 0 + } + + companion object { + @Throws(IllegalArgumentException::class) + @JvmStatic + fun fromLanguageLevel(languageLevel: LanguageLevel): JavaSdkVersion { + val values = JavaSdkVersion.entries.toTypedArray() + if (languageLevel == LanguageLevel.JDK_X) { + return values[values.size - 1] + } + val feature = languageLevel.feature() + if (feature < values.size) { + return values[feature] + } + throw IllegalArgumentException("Can't map " + languageLevel + " to any of " + values.contentToString()) } - throw new IllegalArgumentException("Can't map " + languageLevel + " to any of " + Arrays.toString(values)); - } - /** See {@link JavaVersion#parse(String)} for supported formats. */ - public static @Nullable JavaSdkVersion fromVersionString(@NotNull String versionString) { - JavaVersion version = JavaVersion.tryParse(versionString); - return version != null ? fromJavaVersion(version) : null; - } + /** See [JavaVersion.parse] for supported formats. */ + @JvmStatic + fun fromVersionString(versionString: String): JavaSdkVersion? { + val version = tryParse(versionString) + return if (version != null) fromJavaVersion(version) else null + } - public static @Nullable JavaSdkVersion fromJavaVersion(@NotNull JavaVersion version) { - JavaSdkVersion[] values = values(); - return version.feature < values.length ? values[version.feature] : null; + @JvmStatic + fun fromJavaVersion(version: JavaVersion): JavaSdkVersion? { + val values = JavaSdkVersion.entries.toTypedArray() + return if (version.feature < values.size) values[version.feature] else null + } } } \ No newline at end of file diff --git a/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt similarity index 66% rename from java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java rename to java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt index 5f212b425835..01e71db0aaa4 100644 --- a/java/java-frontback-psi-api/src/com/intellij/pom/java/JavaFeature.java +++ b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt @@ -1,18 +1,18 @@ // Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.pom.java; +package com.intellij.pom.java -import com.intellij.core.JavaPsiBundle; -import org.jetbrains.annotations.*; - -import java.util.Collections; -import java.util.EnumSet; -import java.util.Set; +import com.intellij.java.syntax.JavaSyntaxBundle +import com.intellij.java.syntax.JavaSyntaxBundle.message +import org.jetbrains.annotations.Contract +import org.jetbrains.annotations.Nls +import org.jetbrains.annotations.NonNls +import org.jetbrains.annotations.PropertyKey /** - * Represents Java language, JVM, or standard library features and provides information + * Represents Java language, JVM, or standard library features and provides information * whether a particular features is available in a given context */ -public enum JavaFeature { +enum class JavaFeature { ASSERTIONS(LanguageLevel.JDK_1_4, "feature.assertions"), ENUMS(LanguageLevel.JDK_1_5, "feature.enums"), GENERICS(LanguageLevel.JDK_1_5, "feature.generics"), @@ -82,20 +82,15 @@ public enum JavaFeature { ENUM_QUALIFIED_NAME_IN_SWITCH(LanguageLevel.JDK_21, "feature.enum.qualified.name.in.switch"), SEQUENCED_COLLECTIONS(LanguageLevel.JDK_21, "feature.sequenced.collections"), STRING_TEMPLATES(LanguageLevel.JDK_21_PREVIEW, "feature.string.templates") { - @Override - public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) { - return super.isSufficient(useSiteLevel) && !useSiteLevel.isAtLeast(LanguageLevel.JDK_23); + override fun isSufficient(useSiteLevel: LanguageLevel): Boolean { + return super.isSufficient(useSiteLevel) && !useSiteLevel.isAtLeast(LanguageLevel.JDK_23) } - @Override - public boolean isLimited() { - return true; - } + override val isLimited: Boolean get() = true }, UNNAMED_PATTERNS_AND_VARIABLES(LanguageLevel.JDK_22, "feature.unnamed.vars") { - @Override - public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) { - return super.isSufficient(useSiteLevel) || LanguageLevel.JDK_21_PREVIEW == useSiteLevel; + override fun isSufficient(useSiteLevel: LanguageLevel): Boolean { + return super.isSufficient(useSiteLevel) || LanguageLevel.JDK_21_PREVIEW == useSiteLevel } }, //jep 463,477 @@ -108,7 +103,7 @@ public enum JavaFeature { STREAM_GATHERERS(LanguageLevel.JDK_22_PREVIEW, "feature.stream.gatherers"), STATEMENTS_BEFORE_SUPER(LanguageLevel.JDK_22_PREVIEW, "feature.statements.before.super"), /** - * Was a preview feature in Java 20 Preview. + * Was a preview feature in Java 20 Preview. * Keep the implementation, as it could reappear in the future. */ RECORD_PATTERNS_IN_FOR_EACH(LanguageLevel.JDK_X, "feature.record.patterns.in.for.each", @@ -132,111 +127,95 @@ public enum JavaFeature { VALHALLA_VALUE_CLASSES(LanguageLevel.JDK_X, "feature.valhalla.value.classes"), ; - private final @NotNull LanguageLevel myLevel; - - private final @PropertyKey(resourceBundle = JavaPsiBundle.BUNDLE) @NotNull String myKey; - private final boolean myCanBeCustomized; - private final Set myObsoletePreviewLevels; - - JavaFeature(@NotNull LanguageLevel level, @NotNull @PropertyKey(resourceBundle = JavaPsiBundle.BUNDLE) String key) { - this(level, key, false); - } - - JavaFeature(@NotNull LanguageLevel level, @NotNull @PropertyKey(resourceBundle = JavaPsiBundle.BUNDLE) String key, - @NotNull LanguageLevel @NotNull ... obsoletePreviewLevels) { - myLevel = level; - myKey = key; - myCanBeCustomized = false; - myObsoletePreviewLevels = EnumSet.noneOf(LanguageLevel.class); - for (LanguageLevel obsoletePreviewLevel : obsoletePreviewLevels) { - if (!obsoletePreviewLevel.isUnsupported()) throw new IllegalArgumentException(obsoletePreviewLevel.toString()); - myObsoletePreviewLevels.add(obsoletePreviewLevel); - } - } - - JavaFeature(@NotNull LanguageLevel level, @NotNull @PropertyKey(resourceBundle = JavaPsiBundle.BUNDLE) String key, - boolean canBeCustomized) { - myLevel = level; - myKey = key; - myCanBeCustomized = canBeCustomized; - myObsoletePreviewLevels = Collections.emptySet(); - } - - /** - * @return Human-readable feature name - */ - public @NotNull @Nls String getFeatureName() { - return JavaPsiBundle.message(myKey); - } - /** * @return minimal language level where feature is available. * Note that this doesn't mean that the feature is available on every language level which is higher. - * In most of the cases, {@code PsiUtil.isAvailable(PsiElement)} or {@link #isSufficient(LanguageLevel)} should be used instead. + * In most of the cases, `PsiUtil.isAvailable(PsiElement)` or [.isSufficient] should be used instead. */ - public @NotNull LanguageLevel getMinimumLevel() { - return myLevel; + val minimumLevel: LanguageLevel + + private val myKey: @PropertyKey(resourceBundle = JavaSyntaxBundle.BUNDLE) String + private val myCanBeCustomized: Boolean + private val myObsoletePreviewLevels: Set + + constructor( + level: LanguageLevel, + key: @PropertyKey(resourceBundle = JavaSyntaxBundle.BUNDLE) String, + vararg obsoletePreviewLevels: LanguageLevel + ) { + minimumLevel = level + myKey = key + myCanBeCustomized = false + myObsoletePreviewLevels = mutableSetOf() + for (obsoletePreviewLevel in obsoletePreviewLevels) { + require(obsoletePreviewLevel.isUnsupported) { obsoletePreviewLevel.toString() } + myObsoletePreviewLevels.add(obsoletePreviewLevel) + } + } + + constructor( + level: LanguageLevel, + key: @PropertyKey(resourceBundle = JavaSyntaxBundle.BUNDLE) String, + canBeCustomized: Boolean = false + ) { + minimumLevel = level + myKey = key + myCanBeCustomized = canBeCustomized + myObsoletePreviewLevels = emptySet() } /** - * @return true if the availability of this feature can be additionally filtered using {@link LanguageFeatureProvider}. + * Human-readable feature name + */ + val featureName: @Nls String + get() = message(myKey) + + /** + * @return true if the availability of this feature can be additionally filtered using [LanguageFeatureProvider]. */ @Contract(pure = true) - public boolean canBeCustomized() { - return myCanBeCustomized; + fun canBeCustomized(): Boolean { + return myCanBeCustomized } @Contract(pure = true) - public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) { - return (useSiteLevel.isAtLeast(myLevel) || - useSiteLevel.isUnsupported() && myObsoletePreviewLevels.contains(useSiteLevel)) && - (!myLevel.isPreview() || useSiteLevel.isPreview()); + open fun isSufficient(useSiteLevel: LanguageLevel): Boolean { + return (useSiteLevel.isAtLeast(this.minimumLevel) || + useSiteLevel.isUnsupported && myObsoletePreviewLevels.contains(useSiteLevel)) && + (!minimumLevel.isPreview || useSiteLevel.isPreview) } - @Contract(pure = true) - public boolean isLimited() { - return false; - } + @get:Contract(pure = true) + open val isLimited: Boolean + get() = false /** * Override if feature was preview and then accepted as standard */ - @Contract(pure = true) - public LanguageLevel getStandardLevel() { - return myLevel.isPreview() ? null : myLevel; - } + @get:Contract(pure = true) + val standardLevel: LanguageLevel? + get() = if (minimumLevel.isPreview) null else this.minimumLevel - // Should correspond to jdk.internal.javac.PreviewFeature.Feature enum - @Contract(pure = true) - public static @Nullable JavaFeature convertFromPreviewFeatureName(@NotNull @NonNls String feature) { - switch (feature) { - case "PATTERN_MATCHING_IN_INSTANCEOF": - return PATTERNS; - case "TEXT_BLOCKS": - return TEXT_BLOCKS; - case "RECORDS": - return RECORDS; - case "SEALED_CLASSES": - return SEALED_CLASSES; - case "STRING_TEMPLATES": - return STRING_TEMPLATES; - case "UNNAMED_CLASSES": - case "IMPLICIT_CLASSES": - return IMPLICIT_CLASSES; - case "SCOPED_VALUES": - return SCOPED_VALUES; - case "STRUCTURED_CONCURRENCY": - return STRUCTURED_CONCURRENCY; - case "CLASSFILE_API": - return CLASSFILE_API; - case "STREAM_GATHERERS": - return STREAM_GATHERERS; - case "FOREIGN": - return FOREIGN_FUNCTIONS; - case "VIRTUAL_THREADS": - return VIRTUAL_THREADS; - default: - return null; + companion object { + // Should correspond to jdk.internal.javac.PreviewFeature.Feature enum + @Contract(pure = true) + @JvmStatic + fun convertFromPreviewFeatureName(feature: @NonNls String): JavaFeature? { + return when (feature) { + "PATTERN_MATCHING_IN_INSTANCEOF" -> PATTERNS + "TEXT_BLOCKS" -> TEXT_BLOCKS + "RECORDS" -> RECORDS + "SEALED_CLASSES" -> SEALED_CLASSES + "STRING_TEMPLATES" -> STRING_TEMPLATES + "UNNAMED_CLASSES", "IMPLICIT_CLASSES" -> IMPLICIT_CLASSES + "SCOPED_VALUES" -> SCOPED_VALUES + "STRUCTURED_CONCURRENCY" -> STRUCTURED_CONCURRENCY + "CLASSFILE_API" -> CLASSFILE_API + "STREAM_GATHERERS" -> STREAM_GATHERERS + "FOREIGN" -> FOREIGN_FUNCTIONS + "VIRTUAL_THREADS" -> VIRTUAL_THREADS + else -> null + } } } } diff --git a/java/java-syntax/src/com/intellij/pom/java/LanguageLevel.kt b/java/java-syntax/src/com/intellij/pom/java/LanguageLevel.kt index 6b1ee7cae3b5..9648f0dcdb7c 100644 --- a/java/java-syntax/src/com/intellij/pom/java/LanguageLevel.kt +++ b/java/java-syntax/src/com/intellij/pom/java/LanguageLevel.kt @@ -1,85 +1,81 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -package com.intellij.pom.java; +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.pom.java -import com.intellij.core.JavaPsiBundle; -import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.NlsSafe; -import com.intellij.util.lang.JavaVersion; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; +import com.intellij.java.syntax.JavaSyntaxBundle.messagePointer +import com.intellij.openapi.projectRoots.JavaSdkVersion +import com.intellij.openapi.util.NlsSafe +import com.intellij.util.lang.JavaVersion +import com.intellij.util.lang.JavaVersion.Companion.compose +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.annotations.Nls /** * Represents a language level (i.e. features available) of a Java code. - * The {@link org.jetbrains.jps.model.java.LanguageLevel} class is a compiler-side counterpart of this enum. - *

- * Unsupported language levels are marked as {@link ApiStatus.Obsolete} to draw attention. They should not be normally used, - * except probably in rare tests and inside {@link JavaFeature}. + * The [org.jetbrains.jps.model.java.LanguageLevel] class is a compiler-side counterpart of this enum. + * + * + * Unsupported language levels are marked as [ApiStatus.Obsolete] to draw attention. They should not be normally used, + * except probably in rare tests and inside [JavaFeature]. * * @see com.intellij.openapi.roots.LanguageLevelModuleExtension + * * @see com.intellij.openapi.roots.LanguageLevelProjectExtension + * * @see JavaSdkVersion + * * @see JavaFeature */ -public enum LanguageLevel { - JDK_1_3(JavaPsiBundle.messagePointer("jdk.1.3.language.level.description"), 3), - JDK_1_4(JavaPsiBundle.messagePointer("jdk.1.4.language.level.description"), 4), - JDK_1_5(JavaPsiBundle.messagePointer("jdk.1.5.language.level.description"), 5), - JDK_1_6(JavaPsiBundle.messagePointer("jdk.1.6.language.level.description"), 6), - JDK_1_7(JavaPsiBundle.messagePointer("jdk.1.7.language.level.description"), 7), - JDK_1_8(JavaPsiBundle.messagePointer("jdk.1.8.language.level.description"), 8), - JDK_1_9(JavaPsiBundle.messagePointer("jdk.1.9.language.level.description"), 9), - JDK_10(JavaPsiBundle.messagePointer("jdk.10.language.level.description"), 10), - JDK_11(JavaPsiBundle.messagePointer("jdk.11.language.level.description"), 11), - JDK_12(JavaPsiBundle.messagePointer("jdk.12.language.level.description"), 12), - JDK_13(JavaPsiBundle.messagePointer("jdk.13.language.level.description"), 13), - JDK_14(JavaPsiBundle.messagePointer("jdk.14.language.level.description"), 14), - JDK_15(JavaPsiBundle.messagePointer("jdk.15.language.level.description"), 15), - JDK_16(JavaPsiBundle.messagePointer("jdk.16.language.level.description"), 16), - JDK_17(JavaPsiBundle.messagePointer("jdk.17.language.level.description"), 17), +enum class LanguageLevel { + JDK_1_3(messagePointer("jdk.1.3.language.level.description"), 3), + JDK_1_4(messagePointer("jdk.1.4.language.level.description"), 4), + JDK_1_5(messagePointer("jdk.1.5.language.level.description"), 5), + JDK_1_6(messagePointer("jdk.1.6.language.level.description"), 6), + JDK_1_7(messagePointer("jdk.1.7.language.level.description"), 7), + JDK_1_8(messagePointer("jdk.1.8.language.level.description"), 8), + JDK_1_9(messagePointer("jdk.1.9.language.level.description"), 9), + JDK_10(messagePointer("jdk.10.language.level.description"), 10), + JDK_11(messagePointer("jdk.11.language.level.description"), 11), + JDK_12(messagePointer("jdk.12.language.level.description"), 12), + JDK_13(messagePointer("jdk.13.language.level.description"), 13), + JDK_14(messagePointer("jdk.14.language.level.description"), 14), + JDK_15(messagePointer("jdk.15.language.level.description"), 15), + JDK_16(messagePointer("jdk.16.language.level.description"), 16), + JDK_17(messagePointer("jdk.17.language.level.description"), 17), + @ApiStatus.Obsolete JDK_17_PREVIEW(17), - JDK_18(JavaPsiBundle.messagePointer("jdk.18.language.level.description"), 18), + JDK_18(messagePointer("jdk.18.language.level.description"), 18), + @ApiStatus.Obsolete JDK_18_PREVIEW(18), - JDK_19(JavaPsiBundle.messagePointer("jdk.19.language.level.description"), 19), + JDK_19(messagePointer("jdk.19.language.level.description"), 19), + @ApiStatus.Obsolete JDK_19_PREVIEW(19), - JDK_20(JavaPsiBundle.messagePointer("jdk.20.language.level.description"), 20), + JDK_20(messagePointer("jdk.20.language.level.description"), 20), + @ApiStatus.Obsolete JDK_20_PREVIEW(20), - JDK_21(JavaPsiBundle.messagePointer("jdk.21.language.level.description"), 21), - JDK_21_PREVIEW(JavaPsiBundle.messagePointer("jdk.21.preview.language.level.description"), 21), - JDK_22(JavaPsiBundle.messagePointer("jdk.22.language.level.description"), 22), - JDK_22_PREVIEW(JavaPsiBundle.messagePointer("jdk.22.preview.language.level.description"), 22), - JDK_23(JavaPsiBundle.messagePointer("jdk.23.language.level.description"), 23), - JDK_23_PREVIEW(JavaPsiBundle.messagePointer("jdk.23.preview.language.level.description"), 23), - JDK_24(JavaPsiBundle.messagePointer("jdk.24.language.level.description"), 24), - JDK_24_PREVIEW(JavaPsiBundle.messagePointer("jdk.24.preview.language.level.description"), 24), - JDK_X(JavaPsiBundle.messagePointer("jdk.X.language.level.description"), 25), + JDK_21(messagePointer("jdk.21.language.level.description"), 21), + JDK_21_PREVIEW(messagePointer("jdk.21.preview.language.level.description"), 21), + JDK_22(messagePointer("jdk.22.language.level.description"), 22), + JDK_22_PREVIEW(messagePointer("jdk.22.preview.language.level.description"), 22), + JDK_23(messagePointer("jdk.23.language.level.description"), 23), + JDK_23_PREVIEW(messagePointer("jdk.23.preview.language.level.description"), 23), + JDK_24(messagePointer("jdk.24.language.level.description"), 24), + JDK_24_PREVIEW(messagePointer("jdk.24.preview.language.level.description"), 24), + JDK_X(messagePointer("jdk.X.language.level.description"), 25), ; - /** - * Should point to the latest released JDK. - */ - public static final LanguageLevel HIGHEST = JDK_24; + private val myPresentableText: () -> @Nls String + private val myVersion: JavaVersion + val isPreview: Boolean - private final Supplier<@Nls String> myPresentableText; - private final JavaVersion myVersion; - private final boolean myPreview; - private final boolean myUnsupported; - private static final Map ourStandardVersions = - Stream.of(values()).filter(ver -> !ver.isPreview()) - .collect(Collectors.toMap(ver -> ver.myVersion.feature, Function.identity())); + /** + * @return true if this language level is not supported anymore. It's still possible to invoke compiler or launch the program + * using this language level. However, it's not guaranteed that the code insight features will work correctly. + */ + val isUnsupported: Boolean /** * Construct the language level for a supported Java version @@ -87,11 +83,11 @@ public enum LanguageLevel { * @param presentableTextSupplier a supplier that returns the language level description * @param major the major version number. Whether the version is a preview version is determined by the enum constant name */ - LanguageLevel(Supplier<@Nls String> presentableTextSupplier, int major) { - myPresentableText = presentableTextSupplier; - myVersion = JavaVersion.compose(major); - myUnsupported = false; - myPreview = name().endsWith("_PREVIEW") || name().endsWith("_X"); + constructor(presentableTextSupplier: () -> @Nls String, major: Int) { + myPresentableText = presentableTextSupplier + myVersion = compose(major) + this.isUnsupported = false + this.isPreview = name.endsWith("_PREVIEW") || name.endsWith("_X") } /** @@ -99,60 +95,47 @@ public enum LanguageLevel { * * @param major the major version number. Unsupported Java version is always a preview version */ - LanguageLevel(int major) { - myPresentableText = JavaPsiBundle.messagePointer("jdk.unsupported.preview.language.level.description", major); - myVersion = JavaVersion.compose(major); - myUnsupported = true; - myPreview = true; - if (!name().endsWith("_PREVIEW")) { - throw new IllegalArgumentException("Only preview versions could be unsupported: " + name()); + constructor(major: Int) { + myPresentableText = messagePointer("jdk.unsupported.preview.language.level.description", major) + myVersion = compose(major) + this.isUnsupported = true + this.isPreview = true + require(name.endsWith("_PREVIEW")) { "Only preview versions could be unsupported: " + name } + } + + val previewLevel: LanguageLevel? + /** + * @return corresponding preview level, or `null` if level has no paired preview level + */ + get() { + if (this.isPreview) return this + try { + return valueOf(name + "_PREVIEW") + } + catch (_: IllegalArgumentException) { + return null + } } - } - public boolean isPreview() { - return myPreview; - } - - /** - * @return true if this language level is not supported anymore. It's still possible to invoke compiler or launch the program - * using this language level. However, it's not guaranteed that the code insight features will work correctly. - */ - public boolean isUnsupported() { - return myUnsupported; - } - - /** - * @return corresponding preview level, or {@code null} if level has no paired preview level - */ - public @Nullable LanguageLevel getPreviewLevel() { - if (myPreview) return this; - try { - return valueOf(name() + "_PREVIEW"); + val nonPreviewLevel: LanguageLevel + /** + * @return corresponding non-preview level; this if this level is non-preview already + */ + get() { + if (!this.isPreview) return this + return requireNotNull(ourStandardVersions[myVersion.feature]) } - catch (IllegalArgumentException e) { - return null; - } - } - /** - * @return corresponding non-preview level; this if this level is non-preview already - */ - public @NotNull LanguageLevel getNonPreviewLevel() { - if (!myPreview) return this; - return Objects.requireNonNull(ourStandardVersions.get(myVersion.feature)); - } - - public @NotNull @Nls String getPresentableText() { - return myPresentableText.get(); - } + val presentableText: @Nls String + get() = myPresentableText() /** * @param level level to compare to * @return true, if this language level is at least the same or newer than the level we are comparing to. * A preview level for Java version X is assumed to be between non-preview version X and non-preview version X+1 */ - public boolean isAtLeast(@NotNull LanguageLevel level) { - return compareTo(level) >= 0; + fun isAtLeast(level: LanguageLevel): Boolean { + return compareTo(level) >= 0 } /** @@ -160,58 +143,71 @@ public enum LanguageLevel { * @return true if this language level is strictly less than the level we are comparing to. * A preview level for Java version X is assumed to be between non-preview version X and non-preview version X+1 */ - public boolean isLessThan(@NotNull LanguageLevel level) { - return compareTo(level) < 0; + fun isLessThan(level: LanguageLevel): Boolean { + return compareTo(level) < 0 } /** - * @return the {@link JavaVersion} object that corresponds to this language level + * @return the [JavaVersion] object that corresponds to this language level */ - public @NotNull JavaVersion toJavaVersion() { - return myVersion; + fun toJavaVersion(): JavaVersion { + return myVersion } /** - * @return the language level feature number (like 8 for {@link #JDK_1_8}). + * @return the language level feature number (like 8 for [.JDK_1_8]). */ - public int feature() { - return myVersion.feature; + fun feature(): Int { + return myVersion.feature } - /** - * @return short representation of the corresponding language level, like '8', or '21-preview' - */ - public @NlsSafe String getShortText() { - if (this == JDK_X) { - return "X"; - } - int feature = feature(); - if (feature < 5) { - return "1." + feature; - } - return feature + (isPreview() ? "-preview" : ""); - } - - /** See {@link JavaVersion#parse(String)} for supported formats. */ - public static @Nullable LanguageLevel parse(@Nullable String compilerComplianceOption) { - if (compilerComplianceOption != null) { - JavaSdkVersion sdkVersion = JavaSdkVersion.fromVersionString(compilerComplianceOption); - if (sdkVersion != null) { - return sdkVersion.getMaxLanguageLevel(); + val shortText: @NlsSafe String + /** + * @return short representation of the corresponding language level, like '8', or '21-preview' + */ + get() { + if (this == JDK_X) { + return "X" } + val feature = feature() + if (feature < 5) { + return "1.$feature" + } + return feature.toString() + (if (this.isPreview) "-preview" else "") } - return null; - } - /** - * @param feature major Java language level number - * @return a {@link LanguageLevel} constant that correspond to the specified level (non-preview). - * Returns null for unknown/unsupported input. May return {@link #JDK_X} if language level is one level - * higher than maximal supported. - */ - public static @Nullable LanguageLevel forFeature(int feature) { - return ourStandardVersions.get(feature); - } + companion object { + /** + * Should point to the latest released JDK. + */ + @JvmField + val HIGHEST: LanguageLevel = JDK_24 - public static final Key FILE_LANGUAGE_LEVEL_KEY = Key.create("FORCE_LANGUAGE_LEVEL"); + private val ourStandardVersions: Map = LanguageLevel.entries.asSequence() + .filterNot { ver -> ver.isPreview } + .associateBy { ver -> ver.myVersion.feature } + + /** See [JavaVersion.parse] for supported formats. */ + @JvmStatic + fun parse(compilerComplianceOption: String?): LanguageLevel? { + if (compilerComplianceOption != null) { + val sdkVersion = JavaSdkVersion.fromVersionString(compilerComplianceOption) + if (sdkVersion != null) { + return sdkVersion.maxLanguageLevel + } + } + return null + } + + /** + * @param feature major Java language level number + * @return a [LanguageLevel] constant that correspond to the specified level (non-preview). + * Returns null for unknown/unsupported input. May return [.JDK_X] if language level is one level + * higher than maximal supported. + */ + @JvmStatic + fun forFeature(feature: Int): LanguageLevel? { + return ourStandardVersions[feature] + } + } } \ No newline at end of file diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImportUtil.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImportUtil.kt index 83255f16a599..def4d9d2cd7f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImportUtil.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenImportUtil.kt @@ -29,7 +29,7 @@ import com.intellij.platform.workspace.jps.entities.exModuleOptions import com.intellij.platform.workspace.storage.entities import com.intellij.pom.java.AcceptedLanguageLevelsSettings import com.intellij.pom.java.LanguageLevel -import com.intellij.pom.java.LanguageLevel.HIGHEST +import com.intellij.pom.java.LanguageLevel.Companion.HIGHEST import com.intellij.util.containers.ContainerUtil import com.intellij.util.text.VersionComparatorUtil import com.intellij.workspaceModel.ide.legacyBridge.findModuleEntity @@ -310,14 +310,14 @@ object MavenImportUtil { private fun adjustPreviewLanguageLevel(mavenProject: MavenProject, level: LanguageLevel): LanguageLevel { val enablePreviewProperty = mavenProject.properties.getProperty("maven.compiler.enablePreview") if (enablePreviewProperty.toBoolean()) { - return level.getPreviewLevel() ?: level + return level.previewLevel ?: level } val compilerConfiguration = mavenProject.getPluginConfiguration(COMPILER_PLUGIN_GROUP_ID, COMPILER_PLUGIN_ARTIFACT_ID) if (compilerConfiguration != null) { val enablePreviewParameter = compilerConfiguration.getChildTextTrim("enablePreview") if (enablePreviewParameter.toBoolean()) { - return level.getPreviewLevel() ?: level + return level.previewLevel ?: level } val compilerArgs = compilerConfiguration.getChild("compilerArgs") @@ -326,7 +326,7 @@ object MavenImportUtil { compilerArgs.getChildren("arg").any { isPreviewText(it) } || compilerArgs.getChildren("compilerArg").any{ isPreviewText(it) } ) { - return level.getPreviewLevel() ?: level + return level.previewLevel ?: level } } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.kt b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.kt index 9d9164a88a62..03b3d2322808 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.kt +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/utils/MavenUtil.kt @@ -504,7 +504,7 @@ object MavenUtil { if (sdk != null && sdk.getSdkType() is JavaSdk) { val javaSdk = sdk.getSdkType() as JavaSdk val version: JavaSdkVersion? = javaSdk.getVersion(sdk) - val description = if (version == null) null else version.getDescription() + val description = if (version == null) null else version.description val shouldSetLangLevel = version != null && version.isAtLeast(JavaSdkVersion.JDK_1_6) conditions.setProperty("SHOULD_SET_LANG_LEVEL", shouldSetLangLevel.toString()) properties.setProperty("COMPILER_LEVEL_SOURCE", description)