diff --git a/java/java-backend/resources/META-INF/JavaPlugin.xml b/java/java-backend/resources/META-INF/JavaPlugin.xml
index 2364bf7fa558..43ceeb05a993 100644
--- a/java/java-backend/resources/META-INF/JavaPlugin.xml
+++ b/java/java-backend/resources/META-INF/JavaPlugin.xml
@@ -675,6 +675,7 @@
+
@@ -827,6 +828,8 @@
implementation="com.intellij.codeInsight.template.JavaCodeContextType$JavaStructuredConcurrencyConstructors" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/java/java-backend/resources/liveTemplates/JavaPreviousPreview.xml b/java/java-backend/resources/liveTemplates/JavaPreviousPreview.xml
new file mode 100644
index 000000000000..5cf8f9b842b1
--- /dev/null
+++ b/java/java-backend/resources/liveTemplates/JavaPreviousPreview.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java b/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java
index fecca46e39ca..1527e33fe122 100644
--- a/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java
+++ b/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.template;
import com.intellij.codeInsight.completion.JavaCompletionUtil;
@@ -381,7 +381,22 @@ public abstract class JavaCodeContextType extends TemplateContextType {
@Override
protected boolean isInContext(@NotNull PsiElement element) {
return statementContext.isInContext(element) &&
- PsiUtil.isAvailable(JavaFeature.STRUCTURED_CONCURRENCY_TASK_SCOPE_STATIC_FACTORY_METHODS, element);
+ PsiUtil.isAvailable(JavaFeature.STRUCTURED_CONCURRENCY_TASK_SCOPE_STATIC_FACTORY_METHODS, element) &&
+ !PsiUtil.isAvailable(JavaFeature.STRUCTURED_CONCURRENCY_TASK_SCOPE_STATIC_FACTORY_METHODS_WITH_EXEC_EXCEPTION, element);
+ }
+ }
+
+ public static final class JavaStructuredConcurrencyStaticFactoryMethodsWithExecExceptionType extends JavaCodeContextType {
+ private final JavaCodeContextType statementContext = new Statement();
+
+ JavaStructuredConcurrencyStaticFactoryMethodsWithExecExceptionType() {
+ super(JavaBundle.message("live.template.context.statement.java.structured.concurrency.static.factory.methods.with.exec.exception"));
+ }
+
+ @Override
+ protected boolean isInContext(@NotNull PsiElement element) {
+ return statementContext.isInContext(element) &&
+ PsiUtil.isAvailable(JavaFeature.STRUCTURED_CONCURRENCY_TASK_SCOPE_STATIC_FACTORY_METHODS_WITH_EXEC_EXCEPTION, element);
}
}
}
diff --git a/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt b/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt
index b39219ddeda7..a0fb5ef30432 100644
--- a/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt
+++ b/java/java-syntax/gen/com/intellij/java/syntax/DefaultJavaSyntaxResources.kt
@@ -1,3 +1,4 @@
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.syntax
// To regenerate the file, please run `GenerateBundleMapping` run configuration with the following parameters: ")
@@ -126,6 +127,7 @@ internal object DefaultJavaSyntaxResources {
"feature.structured.concurrency" to "Structured Concurrency",
"feature.structured.concurrency.constructors" to "Structured Concurrency (StructuredTaskScope with constructors)",
"feature.structured.concurrency.static.factory.methods" to "Structured Concurrency (StructuredTaskScope with static factory methods)",
+ "feature.structured.concurrency.static.factory.methods.with.execution.exception" to "Structured Concurrency (StructuredTaskScope with static factory methods and ExecutionException)",
"feature.switch.expressions" to "'switch' expressions",
"feature.text.block.escape.sequences" to "'\\s' escape sequences",
"feature.text.blocks" to "Text block literals",
diff --git a/java/java-syntax/resources/messages/JavaSyntaxBundle.properties b/java/java-syntax/resources/messages/JavaSyntaxBundle.properties
index 256955d69183..c91454c4a3ee 100644
--- a/java/java-syntax/resources/messages/JavaSyntaxBundle.properties
+++ b/java/java-syntax/resources/messages/JavaSyntaxBundle.properties
@@ -73,6 +73,7 @@ feature.stable.values=Stable Values
feature.structured.concurrency=Structured Concurrency
feature.structured.concurrency.constructors=Structured Concurrency (StructuredTaskScope with constructors)
feature.structured.concurrency.static.factory.methods=Structured Concurrency (StructuredTaskScope with static factory methods)
+feature.structured.concurrency.static.factory.methods.with.execution.exception=Structured Concurrency (StructuredTaskScope with static factory methods and ExecutionException)
feature.sequenced.collections=Sequenced Collections
feature.pem.api=PEM Encodings API
feature.classfile.api=ClassFile API
diff --git a/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt
index aeba32b53557..888fcef5c5aa 100644
--- a/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt
+++ b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt
@@ -154,8 +154,17 @@ enum class JavaFeature {
}
},
+ /**
+ * JEP 525
+ */
STRUCTURED_CONCURRENCY_TASK_SCOPE_STATIC_FACTORY_METHODS(LanguageLevel.JDK_25_PREVIEW, "feature.structured.concurrency.static.factory.methods"),
+
+ /**
+ * JEP 533
+ */
+ STRUCTURED_CONCURRENCY_TASK_SCOPE_STATIC_FACTORY_METHODS_WITH_EXEC_EXCEPTION(LanguageLevel.JDK_27_PREVIEW, "feature.structured.concurrency.static.factory.methods.with.execution.exception"),
+
PEM_API(LanguageLevel.JDK_25_PREVIEW, "feature.pem.api"),
/**
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/JavaLiveTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/JavaLiveTemplateTest.java
index 0617d7bf227d..5b10853d1eef 100644
--- a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/JavaLiveTemplateTest.java
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/JavaLiveTemplateTest.java
@@ -1,4 +1,4 @@
-// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.template;
import com.intellij.JavaTestUtil;
@@ -939,7 +939,7 @@ public class JavaLiveTemplateTest extends LiveTemplateTestCase {
}
public void testSTSSAvailable() {
- final TemplateImpl template = TemplateSettings.getInstance().getTemplate("stss", "Java");
+ final TemplateImpl template = TemplateSettings.getInstance().getTemplate("stss", "Java//Previous preview templates");
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20, () -> {
assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
});
@@ -961,25 +961,34 @@ public class JavaLiveTemplateTest extends LiveTemplateTestCase {
}
public void testSTSAvailable() {
- final TemplateImpl template = TemplateSettings.getInstance().getTemplate("sts", "Java");
+ final TemplateImpl previousTemplate = TemplateSettings.getInstance().getTemplate("sts", "Java//Previous preview templates");
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20, () -> {
- assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
+ assertFalse(isApplicable("class Foo {void x(){ JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> {
- assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
+ assertFalse(isApplicable("class Foo {void x(){ JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21_PREVIEW, () -> {
- assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
+ assertFalse(isApplicable("class Foo {void x(){ JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_24_PREVIEW, () -> {
- assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
+ assertFalse(isApplicable("class Foo {void x(){ JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_25, () -> {
- assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
+ assertFalse(isApplicable("class Foo {void x(){ JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_25_PREVIEW, () -> {
+ assertTrue(isApplicable("class Foo {void x(){ JUNK }", previousTemplate));
+ });
+
+ TemplateImpl template = TemplateSettings.getInstance().getTemplate("sts", "Java");
+ IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_26_PREVIEW, () -> {
+ assertFalse(isApplicable("class Foo {void x(){ JUNK }", template));
+ });
+ IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_27_PREVIEW, () -> {
assertTrue(isApplicable("class Foo {void x(){ JUNK }", template));
});
+
}
public void testIOPAvailable() {
diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties
index 5653576d1177..8c4d639267b0 100644
--- a/java/openapi/resources/messages/JavaBundle.properties
+++ b/java/openapi/resources/messages/JavaBundle.properties
@@ -1362,6 +1362,7 @@ live.template.context.declaration=Declaration
live.template.context.statement.java.lang.io=Statement with available java.lang.IO
live.template.context.statement.java.structured.concurrency.constructors=Statement with available StructuredTaskScope with constructors
live.template.context.statement.java.structured.concurrency.static.factory.methods=Statement with available StructuredTaskScope with static factory methods
+live.template.context.statement.java.structured.concurrency.static.factory.methods.with.exec.exception=Statement with available StructuredTaskScope with ExecutionException
live.template.context.normal.class.before.instance.main.declaration=Declaration inside a normal class without instance 'main' method
live.template.context.normal.class.after.instance.main.declaration=Declaration inside a normal class with instance 'main' method
live.template.context.implicit.class.declaration=Declaration inside a compact source file