mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
IDEA-229842 Convert compact constructor to canonical
GitOrigin-RevId: 6edd200e51ec300bf1068d2f040b837fea3f6e1f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d0f72f2f02
commit
b936699772
@@ -1959,6 +1959,10 @@
|
||||
<className>com.intellij.codeInsight.intention.impl.lists.JavaJoinArgumentsAction</className>
|
||||
<category>Java/Other</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.intention.impl.ConvertCompactConstructorToCanonicalAction</className>
|
||||
<category>Java/Declaration</category>
|
||||
</intentionAction>
|
||||
<externalAnnotationsArtifactsResolver implementation="com.intellij.jarRepository.ExternalAnnotationsRepositoryResolver"/>
|
||||
<errorQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.JavaErrorQuickFixProvider"/>
|
||||
<fileTypeDetector implementation="com.intellij.openapi.fileTypes.impl.JavaFileTypeDetector"/>
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
// 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.
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
|
||||
import com.intellij.codeInsight.generation.RecordConstructorMember;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.JavaPsiRecordUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class ConvertCompactConstructorToCanonicalAction extends PsiElementBaseIntentionAction {
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
PsiMethod method = getMethod(element);
|
||||
if (method == null) return;
|
||||
PsiClass recordClass = method.getContainingClass();
|
||||
if (recordClass == null) return;
|
||||
PsiMethod prototype = new RecordConstructorMember(recordClass, false).generateRecordConstructor();
|
||||
PsiModifierList modifierList = method.getModifierList();
|
||||
prototype.getModifierList().replace(modifierList);
|
||||
PsiElement beforeModifier = modifierList.getPrevSibling();
|
||||
if (beforeModifier != null) {
|
||||
prototype.addRangeBefore(method.getFirstChild(), beforeModifier, prototype.getModifierList());
|
||||
}
|
||||
PsiCodeBlock oldBody = Objects.requireNonNull(method.getBody());
|
||||
PsiCodeBlock body = (PsiCodeBlock)Objects.requireNonNull(prototype.getBody()).replace(oldBody);
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
for (PsiRecordComponent component : recordClass.getRecordComponents()) {
|
||||
PsiField field = JavaPsiRecordUtil.getFieldForComponent(component);
|
||||
if (field != null && !HighlightControlFlowUtil.variableDefinitelyAssignedIn(field, body)) {
|
||||
body.add(factory.createStatementFromText("this." + field.getName() + "=" + field.getName() + ";", body));
|
||||
}
|
||||
}
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
if (oldBody.getTextRange().contains(offset)) {
|
||||
offset += body.getTextRangeInParent().getStartOffset() - oldBody.getTextRangeInParent().getStartOffset();
|
||||
}
|
||||
method.replace(prototype);
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@Override
|
||||
public @NotNull String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
PsiMethod method = getMethod(element);
|
||||
return method != null &&
|
||||
JavaPsiRecordUtil.isCompactConstructor(method) &&
|
||||
method.getBody() != null &&
|
||||
method.getContainingClass() != null &&
|
||||
method.getContainingClass().isRecord();
|
||||
}
|
||||
|
||||
private static PsiMethod getMethod(@NotNull PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, PsiMethod.class, true, PsiLambdaExpression.class, PsiMember.class);
|
||||
}
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return CodeInsightBundle.message("intention.convert.compact.constructor.to.canonical");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
record Range(int from, int to) {
|
||||
<spot>public Range(int from, int to) {
|
||||
if (from > to) {
|
||||
from = to;
|
||||
}
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}</spot>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
record Range(int from, int to) {
|
||||
<spot>public Range {
|
||||
if (from > to) {
|
||||
from = to;
|
||||
}
|
||||
}</spot>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
Converts Java record compact constructor to explicit canonical form.
|
||||
<!-- tooltip end -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,22 @@
|
||||
// "Convert compact constructor to canonical" "true"
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
public record Test(int x, @ParamAnno int y, @FieldAnno int... other) {
|
||||
@ConstructorAnno
|
||||
public Test(int x, @ParamAnno int y, int... other) {
|
||||
this.x = Math.abs(x);
|
||||
if (other == null) other = new int[0];
|
||||
this.y = y;
|
||||
this.other = other;
|
||||
}
|
||||
}
|
||||
|
||||
@Target(ElementType.PARAMETER)
|
||||
@interface ParamAnno {}
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@interface FieldAnno {}
|
||||
|
||||
@Target(ElementType.CONSTRUCTOR)
|
||||
@interface ConstructorAnno {}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Convert compact constructor to canonical" "true"
|
||||
record R(int x,int y) {
|
||||
/*
|
||||
hello
|
||||
*/
|
||||
public R(int x, int y) {<caret>
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// "Convert compact constructor to canonical" "true"
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
public record Test(int x, @ParamAnno int y, @FieldAnno int... other) {
|
||||
@ConstructorAnno
|
||||
<caret>public Test {
|
||||
this.x = Math.abs(x);
|
||||
if (other == null) other = new int[0];
|
||||
}
|
||||
}
|
||||
|
||||
@Target(ElementType.PARAMETER)
|
||||
@interface ParamAnno {}
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@interface FieldAnno {}
|
||||
|
||||
@Target(ElementType.CONSTRUCTOR)
|
||||
@interface ConstructorAnno {}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Convert compact constructor to canonical" "true"
|
||||
record R(int x,int y) {
|
||||
/*
|
||||
hello
|
||||
*/
|
||||
public R {<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.java.codeInsight.intention;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
|
||||
|
||||
public class ConvertCompactConstructorToCanonicalActionTest extends LightIntentionActionTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/compactToCanonical";
|
||||
}
|
||||
}
|
||||
@@ -270,6 +270,8 @@ intention.wrap.with.unmodifiable.list=Wrap with unmodifiable list
|
||||
intention.wrap.with.unmodifiable.set=Wrap with unmodifiable set
|
||||
intention.wrap.with.unmodifiable.map=Wrap with unmodifiable map
|
||||
|
||||
intention.convert.compact.constructor.to.canonical=Convert compact constructor to canonical
|
||||
|
||||
intention.preview.adv.show.text=Press {0} to open preview
|
||||
intention.preview.adv.hide.text=Press {0} to hide preview
|
||||
intention.preview.no.available.text=Preview isn't available
|
||||
|
||||
Reference in New Issue
Block a user