[java] IDEA-390263 Support JEP 533: Structured Concurrency (Seventh Preview)

- change live templates

(cherry picked from commit c6edec764b9cbd1567fb1ae3edf240e912172064)

GitOrigin-RevId: 8d40536cd6c706db4c784d51f042ef0d1adcd1ec
This commit is contained in:
Mikhail Pyltsin
2026-07-23 10:59:41 +00:00
committed by intellij-monorepo-bot
parent e29bfdc280
commit 8c0019090e
9 changed files with 78 additions and 28 deletions
@@ -675,6 +675,7 @@
<defaultLiveTemplates file="liveTemplates/Java"/>
<defaultLiveTemplates file="liveTemplates/JavaImplicitClass"/>
<defaultLiveTemplates file="liveTemplates/JavaNormalClassesWithInstanceMain"/>
<defaultLiveTemplates file="liveTemplates/JavaPreviousPreview"/>
<treeStructureProvider id="ClassesTreeStructureProvider" implementation="com.intellij.ide.projectView.impl.ClassesTreeStructureProvider"
order="last, after NestingTreeStructureProvider"/>
<importFilteringRule implementation="com.intellij.usages.impl.rules.ImportFilteringRule"/>
@@ -827,6 +828,8 @@
implementation="com.intellij.codeInsight.template.JavaCodeContextType$JavaStructuredConcurrencyConstructors" />
<liveTemplateContext contextId="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_STATIC_FACTORY_METHODS" baseContextId="JAVA_CODE"
implementation="com.intellij.codeInsight.template.JavaCodeContextType$JavaStructuredConcurrencyStaticFactoryMethods" />
<liveTemplateContext contextId="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_STATIC_FACTORY_METHODS_WITH_EXECUTION_EXCEPTION" baseContextId="JAVA_CODE"
implementation="com.intellij.codeInsight.template.JavaCodeContextType$JavaStructuredConcurrencyStaticFactoryMethodsWithExecExceptionType" />
<liveTemplateContext contextId="JAVA_COMMENT" baseContextId="JAVA_CODE"
implementation="com.intellij.codeInsight.template.JavaCommentContextType"/>
<liveTemplateContext contextId="JAVA_STRING" baseContextId="JAVA_CODE"
@@ -359,27 +359,11 @@
</context>
</template>
<template name="stss" value="try (var scope = new java.util.concurrent.StructuredTaskScope.ShutdownOnSuccess()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle exception&#10;}"
resource-bundle="messages.JavaBundle" key="livetemplate.description.stss" toReformat="true" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_CONSTRUCTORS" value="true" />
</context>
</template>
<template name="stsf" value="try (var scope = new java.util.concurrent.StructuredTaskScope.ShutdownOnFailure()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle exception&#10;}"
resource-bundle="messages.JavaBundle" key="livetemplate.description.stsf" toReformat="true" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_CONSTRUCTORS" value="true" />
</context>
</template>
<template name="sts" value="try (var scope = java.util.concurrent.StructuredTaskScope.open()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle exception&#10;}"
<template name="sts" value="try (var scope = java.util.concurrent.StructuredTaskScope.open()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle interrupted exception&#10;} catch (java.util.concurrent.ExecutionException e) {&#10; // TODO: handle execution exception&#10;}"
resource-bundle="messages.JavaBundle" key="livetemplate.description.sts" toReformat="true" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_STATIC_FACTORY_METHODS" value="true" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_STATIC_FACTORY_METHODS_WITH_EXECUTION_EXCEPTION" value="true" />
</context>
</template>
</templateSet>
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<templateSet group="Java//Previous preview templates">
<template name="stss" value="try (var scope = new java.util.concurrent.StructuredTaskScope.ShutdownOnSuccess()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle exception&#10;}"
resource-bundle="messages.JavaBundle" key="livetemplate.description.stss" toReformat="true" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_CONSTRUCTORS" value="true" />
</context>
</template>
<template name="stsf" value="try (var scope = new java.util.concurrent.StructuredTaskScope.ShutdownOnFailure()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle exception&#10;}"
resource-bundle="messages.JavaBundle" key="livetemplate.description.stsf" toReformat="true" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_CONSTRUCTORS" value="true" />
</context>
</template>
<template name="sts" value="try (var scope = java.util.concurrent.StructuredTaskScope.open()) {&#10; $END$&#10; scope.join();&#10;} catch (InterruptedException e) {&#10; // TODO: handle exception&#10;}"
resource-bundle="messages.JavaBundle" key="livetemplate.description.sts" toReformat="true" toShortenFQNames="true">
<context>
<option name="JAVA_CODE" value="false" />
<option name="JAVA_STATEMENT_WITH_STRUCTURED_CONCURRENCY_STATIC_FACTORY_METHODS" value="true" />
</context>
</template>
</templateSet>
@@ -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);
}
}
}
@@ -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",
@@ -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
@@ -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"),
/**
@@ -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(){ <caret>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(){ <caret>JUNK }", template));
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> {
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", template));
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21_PREVIEW, () -> {
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", template));
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_24_PREVIEW, () -> {
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", template));
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_25, () -> {
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", template));
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", previousTemplate));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_25_PREVIEW, () -> {
assertTrue(isApplicable("class Foo {void x(){ <caret>JUNK }", previousTemplate));
});
TemplateImpl template = TemplateSettings.getInstance().getTemplate("sts", "Java");
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_26_PREVIEW, () -> {
assertFalse(isApplicable("class Foo {void x(){ <caret>JUNK }", template));
});
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_27_PREVIEW, () -> {
assertTrue(isApplicable("class Foo {void x(){ <caret>JUNK }", template));
});
}
public void testIOPAvailable() {
@@ -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