[java] adapt conversion from record to class for old class in presence of unnamed classes

GitOrigin-RevId: 17887007325fda8f9128274bf0d28ce70b5d8c0b
This commit is contained in:
Roman Ivanov
2023-08-27 21:24:26 +00:00
committed by intellij-monorepo-bot
parent bfe4be2085
commit bdc5475282
7 changed files with 27 additions and 53 deletions
@@ -315,7 +315,7 @@
<registryKey key="java.annotations.inference.aggressive.hardcoded.purity" defaultValue="true" restartRequired="true"
description="Assume any implementation of methods like Object.toString() or Iterable.iterator() to be pure during bytecode inference. This assumption might lead to false-positives in some inspections, though it's believed to uncover more bugs."/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.JavaFutureKeywordUseFixProvider"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.quickfix.SealedClassUnresolvedReferenceFixProvider"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.SealedClassUnresolvedReferenceFixProvider"/>
<lang.jvm.annotationPackageSupport implementation="com.intellij.codeInsight.annoPackages.JetBrainsAnnotationSupport"/>
<lang.jvm.annotationPackageSupport implementation="com.intellij.codeInsight.annoPackages.FindBugsAnnotationSupport"/>
<lang.jvm.annotationPackageSupport implementation="com.intellij.codeInsight.annoPackages.AndroidAnnotationSupport"/>
@@ -35,22 +35,6 @@ public class JavaErrorQuickFixProvider implements ErrorQuickFixProvider {
QuickFixFactory.getInstance().createWrapSwitchRuleStatementsIntoBlockFix((PsiSwitchLabeledRuleStatement)parent);
registrar.add(action);
}
if (parent instanceof PsiJavaFile && description.equals(JavaPsiBundle.message("expected.class.or.interface"))) {
PsiElement child = errorElement.getFirstChild();
if (child instanceof PsiIdentifier) {
switch (child.getText()) {
case PsiKeyword.RECORD -> {
HighlightUtil.registerIncreaseLanguageLevelFixes(errorElement, HighlightingFeature.RECORDS, registrar);
if (ConvertRecordToClassFix.tryMakeRecord(errorElement) != null) {
registrar.add(new ConvertRecordToClassFix(errorElement).asIntention());
}
}
case PsiKeyword.SEALED -> HighlightUtil.registerIncreaseLanguageLevelFixes(errorElement, HighlightingFeature.SEALED_CLASSES, registrar);
default -> {
}
}
}
}
QuickFixAction.registerQuickFixActions(info, null, registrar);
}
}
@@ -1,12 +1,14 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
import com.intellij.codeInspection.ConvertRecordToClassFix;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiKeyword;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -23,6 +25,16 @@ public class SealedClassUnresolvedReferenceFixProvider extends UnresolvedReferen
registrar.register(intention);
}
}
if (ref.textMatches(PsiKeyword.RECORD)) {
PsiElement parent = ref.getParent();
if (parent != null) {
if (parent.getParent() instanceof PsiMethod m) {
if (ConvertRecordToClassFix.tryMakeRecord(m) != null) {
registrar.register(m.getTextRange(), new ConvertRecordToClassFix(ref).asIntention(), null);
}
}
}
}
}
@Override
@@ -15,9 +15,7 @@ import com.intellij.modcommand.ActionContext;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.Presentation;
import com.intellij.modcommand.PsiUpdateModCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -81,8 +79,12 @@ public class ConvertRecordToClassFix extends PsiUpdateModCommandAction<PsiElemen
@Override
protected void invoke(@NotNull ActionContext context, @NotNull PsiElement startElement, @NotNull ModPsiUpdater updater) {
PsiClass recordClass;
if (startElement instanceof PsiErrorElement) {
recordClass = tryMakeRecord(startElement);
PsiElement toReplace = startElement;
if (startElement instanceof PsiJavaCodeReferenceElement ref && ref.textMatches("record")) {
PsiMethod method = PsiTreeUtil.getParentOfType(startElement, PsiMethod.class);
if (method == null) return;
recordClass = tryMakeRecord(method);
toReplace = method;
} else {
recordClass = ObjectUtils.tryCast(startElement, PsiClass.class);
}
@@ -97,30 +99,10 @@ public class ConvertRecordToClassFix extends PsiUpdateModCommandAction<PsiElemen
DummyHolder holder = DummyHolderFactory.createHolder(file.getManager(), dummyElement, recordClass);
PsiClass converted = (PsiClass)Objects.requireNonNull(SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()));
postProcessAnnotations(recordClass, converted);
PsiClass result = replace(project, file, startElement, converted);
PsiClass result = (PsiClass)toReplace.replace(converted);
CodeStyleManager.getInstance(project).reformat(JavaCodeStyleManager.getInstance(project).shortenClassReferences(result));
}
private static @NotNull PsiClass replace(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiClass converted) {
if (startElement instanceof PsiErrorElement) {
// Older Java version: try to extract part of code which looks like a record
TextRange range = startElement.getTextRange();
Document document = file.getViewProvider().getDocument();
if (document != null) {
document.replaceString(range.getStartOffset(), range.getEndOffset(), converted.getText());
PsiDocumentManager.getInstance(project).commitDocument(document);
PsiClass pastedClass = PsiTreeUtil.getParentOfType(file.findElementAt(range.getStartOffset()), PsiClass.class);
if (pastedClass != null) {
return pastedClass;
}
}
}
return (PsiClass)startElement.replace(converted);
}
@NotNull
private String generateText(@NotNull PsiClass recordClass) {
PsiField lastField =
@@ -1,6 +1,4 @@
import java.util.Objects;
// "Convert record to class" "true-preview"
import java.util.Objects;// "Convert record to class" "true-preview"
final class Point {
private final double x;
private final double y;
@@ -1,11 +1,9 @@
import java.util.Objects;
// "Convert record to class" "true-preview"
import java.util.Objects;// "Convert record to class" "true-preview"
public final class Point {
private final int x;
private final int y;
Point(int x, int y) {
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@@ -1,4 +1,4 @@
// "Convert record to class" "true-preview"
record Point(double x, double y) {
record Point(double x, double y)<caret> {
void foo() {}
}<caret>
}