From 12e87dec877e1824d00eedf270a843d71855d8c3 Mon Sep 17 00:00:00 2001 From: Mikhail Pyltsin Date: Mon, 18 Nov 2024 18:14:48 +0100 Subject: [PATCH] [java-completion] IDEA-363369 Postfix completion for conversion - more pairs - tests - statistics - improve view GitOrigin-RevId: ac9cca85b73d10a7593c14520601ad7a4f22c0a4 --- .../completion/JavaContributorCollectors.java | 7 ++-- .../JavaEditableTaggedPostfixTemplate.java | 19 ++++++---- .../JavaPostfixTemplateProvider.java | 4 ++- ...avaUtilDateToLocalDatePostfixTemplate.java | 26 ++++++++++++++ ...LocalDateToJavaSqlDatePostfixTemplate.java | 26 ++++++++++++++ .../after.java.template | 3 ++ .../before.java.template | 3 ++ .../description.html | 6 ++++ .../after.java.template | 3 ++ .../before.java.template | 3 ++ .../description.html | 6 ++++ .../postfix/templates/toLocalDate/simple.java | 7 ++++ .../templates/toLocalDate/simple_after.java | 8 +++++ .../postfix/templates/toSqlDate/simple.java | 7 ++++ .../templates/toSqlDate/simple_after.java | 8 +++++ ...tilDateToLocalDatePostfixTemplateTest.java | 28 +++++++++++++++ ...lDateToJavaSqlDatePostfixTemplateTest.java | 35 +++++++++++++++++++ .../tracker/CompletionEventsLoggingTest.kt | 4 +-- 18 files changed, 191 insertions(+), 12 deletions(-) create mode 100644 java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplate.java create mode 100644 java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplate.java create mode 100644 java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/after.java.template create mode 100644 java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/before.java.template create mode 100644 java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/description.html create mode 100644 java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/after.java.template create mode 100644 java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/before.java.template create mode 100644 java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/description.html create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple.java create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple_after.java create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple.java create mode 100644 java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple_after.java create mode 100644 java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplateTest.java create mode 100644 java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplateTest.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaContributorCollectors.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaContributorCollectors.java index 89216b811635..1edb0779d196 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaContributorCollectors.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaContributorCollectors.java @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// 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.codeInsight.completion; import com.intellij.internal.statistic.eventLog.EventLogGroup; @@ -17,11 +17,12 @@ import java.util.List; public final class JavaContributorCollectors extends CounterUsagesCollector { public static final String TAG_TYPE = "tag"; public static final String STATIC_QUALIFIER_TYPE = "static_qualifier"; + public static final String POSTFIX_TAG = "postfix_tag"; - private static final EventLogGroup ourGroup = new EventLogGroup("java.completion.contributors", 2); + private static final EventLogGroup ourGroup = new EventLogGroup("java.completion.contributors", 3); private static final EventField - TYPE_CONTRIBUTOR_FIELD = EventFields.String("type_contributor", List.of(TAG_TYPE, STATIC_QUALIFIER_TYPE)); + TYPE_CONTRIBUTOR_FIELD = EventFields.String("type_contributor", List.of(TAG_TYPE, STATIC_QUALIFIER_TYPE, POSTFIX_TAG)); private static final EventField TYPE_COMPLETION_FIELD = EventFields.String("type_completion", List.of(CompletionType.SMART.name(), CompletionType.BASIC.name())); diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaEditableTaggedPostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaEditableTaggedPostfixTemplate.java index f69579bd9304..d0caac931fcc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaEditableTaggedPostfixTemplate.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaEditableTaggedPostfixTemplate.java @@ -1,6 +1,8 @@ // 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.codeInsight.template.postfix.templates; +import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.codeInsight.completion.JavaContributorCollectors; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.postfix.templates.editable.JavaEditablePostfixTemplate; @@ -15,6 +17,8 @@ import org.jetbrains.annotations.Nullable; import java.util.*; +import static com.intellij.codeInsight.completion.JavaContributorCollectors.POSTFIX_TAG; + @SuppressWarnings("PostfixTemplateDescriptionNotFound") public class JavaEditableTaggedPostfixTemplate extends JavaEditablePostfixTemplate implements CustomizableLookupElementTemplate { @@ -26,9 +30,6 @@ public class JavaEditableTaggedPostfixTemplate extends JavaEditablePostfixTempla @NotNull private final String myExample; - @NotNull - private final String myTemplateName; - public @NotNull String @NotNull [] getTags() { return myTags; } @@ -57,10 +58,10 @@ public class JavaEditableTaggedPostfixTemplate extends JavaEditablePostfixTempla boolean useTopmostExpression, @NotNull String @NotNull [] tags, @NotNull PostfixTemplateProvider provider) { - super(templateId, templateName, liveTemplate, example.replace(EXPR_$, "expr"), expressionConditions, minimumLanguageLevel, useTopmostExpression, provider); + super(templateId, templateName, liveTemplate, example.replace(EXPR_$, "expr"), expressionConditions, minimumLanguageLevel, + useTopmostExpression, provider); myTags = tags; myExample = example; - myTemplateName= templateName; } @@ -77,7 +78,7 @@ public class JavaEditableTaggedPostfixTemplate extends JavaEditablePostfixTempla public void renderElement(@NotNull LookupElementPresentation presentation) { String exp = myText; String templateText = myExample; - if (exp == null || templateText.length() + exp.length() >= 50 || !templateText.contains(EXPR_$)) { + if (exp == null || templateText.length() + exp.length() >= 100 || !templateText.contains(EXPR_$)) { return; } String withExp = templateText.replace(EXPR_$, exp); @@ -103,4 +104,10 @@ public class JavaEditableTaggedPostfixTemplate extends JavaEditablePostfixTempla public Collection getAllLookupStrings() { return Arrays.asList(myTags); } + + @Override + protected @NotNull TextRange getRangeToRemove(@NotNull PsiElement element) { + JavaContributorCollectors.logInsertHandle(element.getProject(), POSTFIX_TAG, CompletionType.BASIC); + return super.getRangeToRemove(element); + } } diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java index 8652bdf9b2d7..3757de5742f3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaPostfixTemplateProvider.java @@ -76,7 +76,9 @@ public class JavaPostfixTemplateProvider implements PostfixTemplateProvider { new AsListToListPostfixTemplate(this), new ListOfToListPostfixTemplate(this), new NewArrayListToListPostfixTemplate(this), - new NewHashSetToSetPostfixTemplate(this) + new NewHashSetToSetPostfixTemplate(this), + new LocalDateToJavaSqlDatePostfixTemplate(this), + new JavaUtilDateToLocalDatePostfixTemplate(this) ); @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplate.java new file mode 100644 index 000000000000..48a07f5f5eaa --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplate.java @@ -0,0 +1,26 @@ +// 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.codeInsight.template.postfix.templates; + +import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; +import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +public class JavaUtilDateToLocalDatePostfixTemplate extends JavaEditableTaggedPostfixTemplate implements DumbAware { + public JavaUtilDateToLocalDatePostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { + super("LocalDate.ofInstant(exp.toInstant(), zoneId) java.sql.Date.valueOf(exp)", + "toLocalDate", + "java.time.LocalDate.ofInstant($EXPR$.toInstant(), $END$)", + "LocalDate.ofInstant($EXPR$.toInstant(), zoneId)", + Collections.singleton( + new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateExpressionFqnCondition("java.util.Date")), + LanguageLevel.JDK_1_8, false, new String[]{".asLocalDate"}, provider); + } + + @Override + public boolean isBuiltin() { + return true; + } +} diff --git a/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplate.java b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplate.java new file mode 100644 index 000000000000..6e823e7c63c3 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplate.java @@ -0,0 +1,26 @@ +// 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.codeInsight.template.postfix.templates; + +import com.intellij.codeInsight.template.postfix.templates.editable.JavaPostfixTemplateExpressionCondition; +import com.intellij.openapi.project.DumbAware; +import com.intellij.pom.java.LanguageLevel; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +public class LocalDateToJavaSqlDatePostfixTemplate extends JavaEditableTaggedPostfixTemplate implements DumbAware { + public LocalDateToJavaSqlDatePostfixTemplate(@NotNull JavaPostfixTemplateProvider provider) { + super("java.sql.Date.valueOf(exp)", + "sqlValueOf", + "java.sql.Date.valueOf($EXPR$)$END$", + "java.sql.Date.valueOf($EXPR$)", + Collections.singleton( + new JavaPostfixTemplateExpressionCondition.JavaPostfixTemplateExpressionFqnCondition("java.time.LocalDate")), + LanguageLevel.JDK_1_8, false, new String[]{".toSqlDate"}, provider); + } + + @Override + public boolean isBuiltin() { + return true; + } +} diff --git a/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/after.java.template b/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/after.java.template new file mode 100644 index 000000000000..0f3438ac5da5 --- /dev/null +++ b/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/after.java.template @@ -0,0 +1,3 @@ +public void m(Date value) { + LocalDate.ofInstant(value.toInstant(), ) +} \ No newline at end of file diff --git a/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/before.java.template b/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/before.java.template new file mode 100644 index 000000000000..bc6b644d686c --- /dev/null +++ b/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/before.java.template @@ -0,0 +1,3 @@ +public void m(Date value) { + value$key +} \ No newline at end of file diff --git a/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/description.html b/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/description.html new file mode 100644 index 000000000000..df8b48f2f909 --- /dev/null +++ b/java/java-impl/src/postfixTemplates/JavaUtilDateToLocalDatePostfixTemplate/description.html @@ -0,0 +1,6 @@ + + +Creates a LocalDate with call LocalDate.ofInstant for a java.util.Date expression. +It is necessary to define ZoneId. + + diff --git a/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/after.java.template b/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/after.java.template new file mode 100644 index 000000000000..c3d93344980b --- /dev/null +++ b/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/after.java.template @@ -0,0 +1,3 @@ +public void m(LocalDate value) { + java.sql.Date(value) +} \ No newline at end of file diff --git a/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/before.java.template b/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/before.java.template new file mode 100644 index 000000000000..ff8bb2c42467 --- /dev/null +++ b/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/before.java.template @@ -0,0 +1,3 @@ +public void m(LocalDate value) { + value$key +} \ No newline at end of file diff --git a/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/description.html b/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/description.html new file mode 100644 index 000000000000..c8f68ec14232 --- /dev/null +++ b/java/java-impl/src/postfixTemplates/LocalDateToJavaSqlDatePostfixTemplate/description.html @@ -0,0 +1,6 @@ + + + +Creates a java.sql.Date.valueOf call for a java.time.LocalDate expression. + + diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple.java b/java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple.java new file mode 100644 index 000000000000..ae28d2ef9469 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple.java @@ -0,0 +1,7 @@ +import java.util.Date; + +public class Foo { + void m(Date o) { + o.toLocalDate + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple_after.java new file mode 100644 index 000000000000..8b0fc624c50c --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/toLocalDate/simple_after.java @@ -0,0 +1,8 @@ +import java.time.LocalDate; +import java.util.Date; + +public class Foo { + void m(Date o) { + LocalDate.ofInstant(o.toInstant(), ) + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple.java b/java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple.java new file mode 100644 index 000000000000..4e40def3aa49 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple.java @@ -0,0 +1,7 @@ +import java.time.LocalDate; + +public class Foo { + void m(LocalDate o) { + o.toSqlDate + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple_after.java b/java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple_after.java new file mode 100644 index 000000000000..d5daca6db5d1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/template/postfix/templates/toSqlDate/simple_after.java @@ -0,0 +1,8 @@ +import java.sql.Date; +import java.time.LocalDate; + +public class Foo { + void m(LocalDate o) { + Date.valueOf(o) + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplateTest.java new file mode 100644 index 000000000000..9c4a27a4f724 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/JavaUtilDateToLocalDatePostfixTemplateTest.java @@ -0,0 +1,28 @@ +// 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.java.codeInsight.template.postfix.templates; + +import com.intellij.testFramework.LightProjectDescriptor; +import org.jetbrains.annotations.NotNull; + +public class JavaUtilDateToLocalDatePostfixTemplateTest extends PostfixTemplateTestCase { + + @Override + protected @NotNull LightProjectDescriptor getProjectDescriptor() { + return JAVA_8; + } + + @NotNull + @Override + protected String getSuffix() { + return "toLocalDate"; + } + + public void testSimple() { + myFixture.addClass(""" + package java.time; + public final class LocalDate { } + """); + doTestCompletion("toLocalDate"); + } +} + diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplateTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplateTest.java new file mode 100644 index 000000000000..cd0a9daa5ef4 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/template/postfix/templates/LocalDateToJavaSqlDatePostfixTemplateTest.java @@ -0,0 +1,35 @@ +// 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.java.codeInsight.template.postfix.templates; + +import com.intellij.testFramework.LightProjectDescriptor; +import org.jetbrains.annotations.NotNull; + +public class LocalDateToJavaSqlDatePostfixTemplateTest extends PostfixTemplateTestCase { + + @Override + protected @NotNull LightProjectDescriptor getProjectDescriptor() { + return JAVA_8; + } + + @NotNull + @Override + protected String getSuffix() { + return "toSqlDate"; + } + + public void testSimple() { + myFixture.addClass(""" + package java.time; + public final class LocalDate { } + """); + myFixture.addClass(""" + package java.sql; + import java.time.LocalDate; + public final class Date {\s + public static Date valueOf(LocalDate date) { return null; } + } + """); + doTestCompletion("toSqlDate"); + } +} + diff --git a/plugins/stats-collector/test/com/intellij/stats/completion/tracker/CompletionEventsLoggingTest.kt b/plugins/stats-collector/test/com/intellij/stats/completion/tracker/CompletionEventsLoggingTest.kt index eb7d532d505c..e71bb9f89468 100644 --- a/plugins/stats-collector/test/com/intellij/stats/completion/tracker/CompletionEventsLoggingTest.kt +++ b/plugins/stats-collector/test/com/intellij/stats/completion/tracker/CompletionEventsLoggingTest.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2020 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-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.stats.completion.tracker import com.intellij.codeInsight.lookup.LookupElement @@ -64,7 +64,7 @@ class CompletionEventsLoggingTest : CompletionLoggingTestBase() { myFixture.type('u') myFixture.type('x') - lookup.hide() //figure out why needed here + lookup?.hide() //figure out why needed here trackedEvents.assertOrder( COMPLETION_STARTED,