From 7b6981f118a037b8ebcd975bdcd4d1c5ac2d3d14 Mon Sep 17 00:00:00 2001 From: Mikhail Pyltsin Date: Wed, 11 Jun 2025 20:19:11 +0200 Subject: [PATCH] [java] IDEA-373074 Improve SOUT templates for java 25 GitOrigin-RevId: 688a0f2ccefaa6f3f9b51c8528fa11e61d0798b0 --- .../resources/META-INF/JavaPlugin.xml | 2 + .../template/JavaCodeContextType.java | 12 +++ .../intellij/codeInsight/TypeNullability.java | 1 + .../src/com/intellij/psi/GenericsUtil.java | 3 +- .../messages/JavaSyntaxBundle.properties | 1 + .../src/com/intellij/pom/java/JavaFeature.kt | 3 + .../template/JavaLiveTemplateTest.java | 77 ++++++++++++++++++- .../resources/messages/JavaBundle.properties | 1 + .../messages/CodeInsightBundle.properties | 2 + resources/src/liveTemplates/Java.xml | 12 +++ 10 files changed, 112 insertions(+), 2 deletions(-) diff --git a/java/java-impl/resources/META-INF/JavaPlugin.xml b/java/java-impl/resources/META-INF/JavaPlugin.xml index 54aaa60c7d90..e8eaf62f8d50 100644 --- a/java/java-impl/resources/META-INF/JavaPlugin.xml +++ b/java/java-impl/resources/META-INF/JavaPlugin.xml @@ -1191,6 +1191,8 @@ implementation="com.intellij.codeInsight.template.JavaCodeContextType$ImplicitClassDeclaration"/> + sources = map.get(Nullability.NOT_NULL); if (sources != null) { + //todo? return new TypeNullability(Nullability.NOT_NULL, NullabilitySource.multiSource(sources)); } sources = map.get(Nullability.NULLABLE); diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java index 1f7765157019..42ce3d97e380 100644 --- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java @@ -328,7 +328,7 @@ public final class GenericsUtil { if (wildcardType.isSuper() && bound instanceof PsiIntersectionType) { return PsiWildcardType.createUnbounded(manager); } - +//todo final PsiType acceptedBound = bound.accept(this); if (acceptedBound instanceof PsiWildcardType) { if (((PsiWildcardType)acceptedBound).isExtends() != wildcardType.isExtends()) return PsiWildcardType.createUnbounded(manager); @@ -394,6 +394,7 @@ public final class GenericsUtil { PsiType componentType = transformed.getDeepComponentType(); if (componentType instanceof PsiWildcardType) { componentType = ((PsiWildcardType)componentType).getExtendsBound(); + //todo return PsiTypesUtil.createArrayType(componentType, transformed.getArrayDimensions()); } if (transformed instanceof PsiEllipsisType) { diff --git a/java/java-syntax/resources/messages/JavaSyntaxBundle.properties b/java/java-syntax/resources/messages/JavaSyntaxBundle.properties index 814e32c76d39..c3ca5b7deca3 100644 --- a/java/java-syntax/resources/messages/JavaSyntaxBundle.properties +++ b/java/java-syntax/resources/messages/JavaSyntaxBundle.properties @@ -79,6 +79,7 @@ feature.package.import.shadow.module.import=Import-on-demand over module import feature.package.transitive.dependency.on.java.base=Transitive dependency on java.base module feature.valhalla.value.classes=Valhalla value classes feature.markdown.comment=Markdown Documentation Comments +feature.java.lang.io=java.lang.IO utility class else.without.if='else' without 'if' expected.array.initializer=Array initializer expected 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 752dfc4d3dee..0ea4879436ee 100644 --- a/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt +++ b/java/java-syntax/src/com/intellij/pom/java/JavaFeature.kt @@ -131,6 +131,9 @@ enum class JavaFeature { MARKDOWN_COMMENT(LanguageLevel.JDK_23, "feature.markdown.comment"), PACKAGE_IMPORTS_SHADOW_MODULE_IMPORTS(LanguageLevel.JDK_24_PREVIEW, "feature.package.import.shadow.module.import"), TRANSITIVE_DEPENDENCY_ON_JAVA_BASE(LanguageLevel.JDK_24_PREVIEW, "feature.package.transitive.dependency.on.java.base"), + + JAVA_LANG_IO(LanguageLevel.JDK_25, "feature.java.lang.io"), + VALHALLA_VALUE_CLASSES(LanguageLevel.JDK_X, "feature.valhalla.value.classes"), ; 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 797427691593..94b1910bd27e 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 @@ -5,7 +5,6 @@ import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.daemon.impl.quickfix.EmptyExpression; import com.intellij.codeInsight.lookup.Lookup; -import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.template.*; import com.intellij.codeInsight.template.actions.SaveAsTemplateAction; import com.intellij.codeInsight.template.impl.*; @@ -859,6 +858,82 @@ public class JavaLiveTemplateTest extends LiveTemplateTestCase { ); } + public void testIOP() { + IdeaTestUtil.withLevel( + getModule(), + JavaFeature.JAVA_LANG_IO.getMinimumLevel(), + () -> { + myFixture.configureByText( + "a.java", + """ + class A{ + public static void main(String[] args) { + + } + } + """); + final TemplateImpl template = TemplateSettings.getInstance().getTemplate("iop", "Java"); + startTemplate(template); + myFixture.checkResult( + """ + class A{ + public static void main(String[] args) { + IO.println(); + } + } + """); + } + ); + } + + public void testIOR() { + IdeaTestUtil.withLevel( + getModule(), + JavaFeature.JAVA_LANG_IO.getMinimumLevel(), + () -> { + myFixture.configureByText( + "a.java", + """ + class A{ + public static void main(String[] args) { + + } + }"""); + final TemplateImpl template = TemplateSettings.getInstance().getTemplate("ior", "Java"); + startTemplate(template); + myFixture.checkResult( + """ + class A{ + public static void main(String[] args) { + IO.readln(); + } + }"""); + } + ); + } + + public void testIOPAvailable() { + final TemplateImpl template = + TemplateSettings.getInstance().getTemplate("iop", "Java"); + IdeaTestUtil.withLevel(getModule(), JavaFeature.JAVA_LANG_IO.getMinimumLevel(), () -> { + assertTrue(isApplicable("class Foo {void x(){ JUNK }", template)); + }); + IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> { + assertFalse(isApplicable("class Foo {void x(){ JUNK }", template)); + }); + } + + public void testIORAvailable() { + final TemplateImpl template = + TemplateSettings.getInstance().getTemplate("ior", "Java"); + IdeaTestUtil.withLevel(getModule(), JavaFeature.JAVA_LANG_IO.getMinimumLevel(), () -> { + assertTrue(isApplicable("class Foo {void x(){ JUNK }", template)); + }); + IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> { + assertFalse(isApplicable("class Foo {void x(){ JUNK }", template)); + }); + } + @Override public final String getBasePath() { return basePath; diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties index daead1566458..cd7a6e4670ce 100644 --- a/java/openapi/resources/messages/JavaBundle.properties +++ b/java/openapi/resources/messages/JavaBundle.properties @@ -1320,6 +1320,7 @@ live.template.context.statement=Statement live.template.context.else='else' position live.template.context.expression=Expression live.template.context.declaration=Declaration +live.template.context.statement.java.lang.io=Statement with available java.lang.IO 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 an implicitly declared class diff --git a/platform/lang-api/resources/messages/CodeInsightBundle.properties b/platform/lang-api/resources/messages/CodeInsightBundle.properties index ef9f94b36c18..137085c2cbd6 100644 --- a/platform/lang-api/resources/messages/CodeInsightBundle.properties +++ b/platform/lang-api/resources/messages/CodeInsightBundle.properties @@ -208,6 +208,8 @@ livetemplate.description.souf=Prints a formatted string to System.out livetemplate.description.soutm=Prints current class and method names to System.out livetemplate.description.soutp=Prints method parameter names and values to System.out livetemplate.description.soutv=Prints a value to System.out +livetemplate.description.iop=IO.println() +livetemplate.description.ior=IO.readln() livetemplate.description.st=String livetemplate.description.psf=public static final livetemplate.description.prsf=private static final diff --git a/resources/src/liveTemplates/Java.xml b/resources/src/liveTemplates/Java.xml index 6bfa90da24b0..db4482b915df 100644 --- a/resources/src/liveTemplates/Java.xml +++ b/resources/src/liveTemplates/Java.xml @@ -268,6 +268,18 @@