Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,16 @@ private static <T extends PsiElement> void checkDuplicateRefs(
for (T statement : statements) {
String refText = ref.apply(statement).orElse(null);
if (refText != null && !filter.add(refText)) {
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
HighlightInfo.Builder hlBuilder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.range(statement)
.descriptionAndTooltip(descriptionTemplate.apply(refText))
.registerFix(factory().createDeleteFix(statement))
.registerFix(MergeModuleStatementsFix.createFix(statement))
.create();
results.add(info);
.registerFix(factory().createDeleteFix(statement));

MergeModuleStatementsFix mergeModuleStatementsFix = MergeModuleStatementsFix.createFix(statement);
if (mergeModuleStatementsFix != null) {
hlBuilder.registerFix(mergeModuleStatementsFix);
}
results.add(hlBuilder.create());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import com.intellij.java.language.psi.*;
import com.intellij.java.language.psi.util.PsiUtil;
import com.siyeh.ig.psiutils.CommentTracker;
import consulo.annotation.access.RequiredReadAction;
import consulo.annotation.access.RequiredWriteAction;
import consulo.codeEditor.Editor;
import consulo.language.codeStyle.CodeStyleManager;
import consulo.language.editor.inspection.LocalQuickFixAndIntentionActionOnPsiElement;
Expand All @@ -27,6 +29,7 @@
import jakarta.annotation.Nonnull;

import jakarta.annotation.Nullable;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
Expand All @@ -36,67 +39,79 @@
* @author Pavel.Dolgov
*/
public abstract class MergeModuleStatementsFix<T extends PsiElement> extends LocalQuickFixAndIntentionActionOnPsiElement {
protected MergeModuleStatementsFix(@Nonnull PsiJavaModule javaModule) {
super(javaModule);
}

protected MergeModuleStatementsFix(@Nonnull PsiJavaModule javaModule) {
super(javaModule);
}

@Override
public boolean isAvailable(@Nonnull Project project, @Nonnull PsiFile file, @Nonnull PsiElement startElement, @Nonnull PsiElement endElement) {
return PsiUtil.isLanguageLevel9OrHigher(file);
}
@Override
@RequiredReadAction
public boolean isAvailable(
@Nonnull Project project,
@Nonnull PsiFile file,
@Nonnull PsiElement startElement,
@Nonnull PsiElement endElement
) {
return PsiUtil.isLanguageLevel9OrHigher(file);
}

@Override
public void invoke(@Nonnull Project project, @Nonnull PsiFile file, @Nullable Editor editor, @Nonnull PsiElement startElement, @Nonnull PsiElement endElement) {
if (startElement instanceof PsiJavaModule) {
final PsiJavaModule javaModule = (PsiJavaModule) startElement;
final List<T> statementsToMerge = getStatementsToMerge(javaModule);
LOG.assertTrue(!statementsToMerge.isEmpty());
@Override
@RequiredWriteAction
public void invoke(
@Nonnull Project project,
@Nonnull PsiFile file,
@Nullable Editor editor,
@Nonnull PsiElement startElement,
@Nonnull PsiElement endElement
) {
if (startElement instanceof PsiJavaModule javaModule) {
List<T> statementsToMerge = getStatementsToMerge(javaModule);
LOG.assertTrue(!statementsToMerge.isEmpty());

final String tempModuleText = PsiKeyword.MODULE + " " + javaModule.getName() + " {" + getReplacementText(statementsToMerge) + "}";
final PsiJavaModule tempModule = JavaPsiFacade.getInstance(project).getElementFactory().createModuleFromText(tempModuleText);
String tempModuleText =
PsiKeyword.MODULE + " " + javaModule.getName() + " {" + getReplacementText(statementsToMerge) + "}";
PsiJavaModule tempModule = JavaPsiFacade.getInstance(project).getElementFactory().createModuleFromText(tempModuleText);

final List<T> tempStatements = getStatementsToMerge(tempModule);
LOG.assertTrue(!tempStatements.isEmpty());
final T replacement = tempStatements.get(0);
List<T> tempStatements = getStatementsToMerge(tempModule);
LOG.assertTrue(!tempStatements.isEmpty());
T replacement = tempStatements.get(0);

final T firstStatement = statementsToMerge.get(0);
final CommentTracker commentTracker = new CommentTracker();
final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
final PsiElement resultingStatement = codeStyleManager.reformat(commentTracker.replace(firstStatement, replacement));
T firstStatement = statementsToMerge.get(0);
CommentTracker commentTracker = new CommentTracker();
CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(project);
PsiElement resultingStatement = codeStyleManager.reformat(commentTracker.replace(firstStatement, replacement));

for (int i = 1; i < statementsToMerge.size(); i++) {
T statement = statementsToMerge.get(i);
commentTracker.delete(statement);
}
commentTracker.insertCommentsBefore(resultingStatement);
for (int i = 1; i < statementsToMerge.size(); i++) {
T statement = statementsToMerge.get(i);
commentTracker.delete(statement);
}
commentTracker.insertCommentsBefore(resultingStatement);

if (editor != null) {
final int offset = resultingStatement.getTextRange().getEndOffset();
editor.getCaretModel().moveToOffset(offset);
}
if (editor != null) {
int offset = resultingStatement.getTextRange().getEndOffset();
editor.getCaretModel().moveToOffset(offset);
}
}
}
}

@Nonnull
protected abstract String getReplacementText(List<T> statementsToMerge);
@Nonnull
protected abstract String getReplacementText(List<T> statementsToMerge);

@Nonnull
protected abstract List<T> getStatementsToMerge(@Nonnull PsiJavaModule javaModule);
@Nonnull
protected abstract List<T> getStatementsToMerge(@Nonnull PsiJavaModule javaModule);

@Nonnull
protected static String joinUniqueNames(@Nonnull List<String> names) {
final Set<String> unique = new HashSet<>();
return names.stream().filter(name -> unique.add(name)).collect(Collectors.joining(","));
}
@Nonnull
protected static String joinUniqueNames(@Nonnull List<String> names) {
return names.stream().distinct().collect(Collectors.joining(","));
}

@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiElement statement) {
if (statement instanceof PsiPackageAccessibilityStatement) {
return MergePackageAccessibilityStatementsFix.createFix((PsiPackageAccessibilityStatement) statement);
} else if (statement instanceof PsiProvidesStatement) {
return MergeProvidesStatementsFix.createFix((PsiProvidesStatement) statement);
@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiElement statement) {
if (statement instanceof PsiPackageAccessibilityStatement packageAccessibilityStmt) {
return MergePackageAccessibilityStatementsFix.createFix(packageAccessibilityStmt);
}
else if (statement instanceof PsiProvidesStatement providesStmt) {
return MergeProvidesStatementsFix.createFix(providesStmt);
}
return null;
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@
import com.intellij.java.language.psi.PsiKeyword;
import com.intellij.java.language.psi.PsiPackageAccessibilityStatement;
import com.intellij.java.language.psi.PsiPackageAccessibilityStatement.Role;
import consulo.java.analysis.impl.JavaQuickFixBundle;
import consulo.language.psi.PsiElement;
import consulo.java.analysis.impl.localize.JavaQuickFixLocalize;
import consulo.logging.Logger;
import org.jetbrains.annotations.Nls;

import jakarta.annotation.Nonnull;
import jakarta.annotation.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -36,95 +34,83 @@
* @author Pavel.Dolgov
*/
public class MergePackageAccessibilityStatementsFix extends MergeModuleStatementsFix<PsiPackageAccessibilityStatement> {
private static final Logger LOG = Logger.getInstance(MergePackageAccessibilityStatementsFix.class);
private final String myPackageName;
private final Role myRole;

private static final Logger LOG = Logger.getInstance(MergePackageAccessibilityStatementsFix.class);
private final String myPackageName;
private final Role myRole;

protected MergePackageAccessibilityStatementsFix(@Nonnull PsiJavaModule javaModule, @Nonnull String packageName, @Nonnull Role role) {
super(javaModule);
myPackageName = packageName;
myRole = role;
}
protected MergePackageAccessibilityStatementsFix(@Nonnull PsiJavaModule javaModule, @Nonnull String packageName, @Nonnull Role role) {
super(javaModule);
myPackageName = packageName;
myRole = role;
}

@Nls
@Nonnull
@Override
public String getText() {
return JavaQuickFixBundle.message("java.9.merge.module.statements.fix.name", getKeyword(), myPackageName);
}
@Nonnull
@Override
public String getText() {
return JavaQuickFixLocalize.java9MergeModuleStatementsFixName(getKeyword(), myPackageName).get();
}

@Nls
@Nonnull
@Override
public String getFamilyName() {
return JavaQuickFixBundle.message("java.9.merge.module.statements.fix.family.name", getKeyword());
}
@Nonnull
@Override
public String getFamilyName() {
return JavaQuickFixLocalize.java9MergeModuleStatementsFixFamilyName(getKeyword()).get();
}

@Nonnull
@Override
protected String getReplacementText(@Nonnull List<PsiPackageAccessibilityStatement> statementsToMerge) {
final List<String> moduleNames = getModuleNames(statementsToMerge);
if (!moduleNames.isEmpty()) {
return getKeyword() + " " + myPackageName + " " + PsiKeyword.TO + " " + joinUniqueNames(moduleNames) + ";";
@Nonnull
@Override
protected String getReplacementText(@Nonnull List<PsiPackageAccessibilityStatement> statementsToMerge) {
List<String> moduleNames = getModuleNames(statementsToMerge);
if (!moduleNames.isEmpty()) {
return getKeyword() + " " + myPackageName + " " + PsiKeyword.TO + " " + joinUniqueNames(moduleNames) + ";";
}
return getKeyword() + " " + myPackageName + ";";
}
return getKeyword() + " " + myPackageName + ";";
}

@Nonnull
private static List<String> getModuleNames(@Nonnull List<PsiPackageAccessibilityStatement> statements) {
final List<String> result = new ArrayList<>();
for (PsiPackageAccessibilityStatement statement : statements) {
final List<String> moduleNames = statement.getModuleNames();
if (moduleNames.isEmpty()) {
return Collections.emptyList();
}
result.addAll(moduleNames);
@Nonnull
private static List<String> getModuleNames(@Nonnull List<PsiPackageAccessibilityStatement> statements) {
List<String> result = new ArrayList<>();
for (PsiPackageAccessibilityStatement statement : statements) {
List<String> moduleNames = statement.getModuleNames();
if (moduleNames.isEmpty()) {
return Collections.emptyList();
}
result.addAll(moduleNames);
}
return result;
}
return result;
}

@Nonnull
@Override
protected List<PsiPackageAccessibilityStatement> getStatementsToMerge(@Nonnull PsiJavaModule javaModule) {
return StreamSupport.stream(getStatements(javaModule, myRole).spliterator(), false).filter(statement -> myPackageName.equals(statement.getPackageName())).collect(Collectors.toList());
}
@Nonnull
@Override
protected List<PsiPackageAccessibilityStatement> getStatementsToMerge(@Nonnull PsiJavaModule javaModule) {
return StreamSupport.stream(getStatements(javaModule, myRole).spliterator(), false)
.filter(statement -> myPackageName.equals(statement.getPackageName()))
.collect(Collectors.toList());
}

@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiPackageAccessibilityStatement statement) {
if (statement != null) {
final PsiElement parent = statement.getParent();
if (parent instanceof PsiJavaModule) {
final String packageName = statement.getPackageName();
if (packageName != null) {
return new MergePackageAccessibilityStatementsFix((PsiJavaModule) parent, packageName, statement.getRole());
@Nullable
public static MergeModuleStatementsFix createFix(@Nullable PsiPackageAccessibilityStatement statement) {
if (statement != null && statement.getParent() instanceof PsiJavaModule javaModule) {
String packageName = statement.getPackageName();
if (packageName != null) {
return new MergePackageAccessibilityStatementsFix(javaModule, packageName, statement.getRole());
}
}
}
return null;
}
return null;
}

@Nonnull
private static Iterable<PsiPackageAccessibilityStatement> getStatements(@Nonnull PsiJavaModule javaModule, @Nonnull Role role) {
switch (role) {
case OPENS:
return javaModule.getOpens();
case EXPORTS:
return javaModule.getExports();
@Nonnull
private static Iterable<PsiPackageAccessibilityStatement> getStatements(@Nonnull PsiJavaModule javaModule, @Nonnull Role role) {
return switch (role) {
case OPENS -> javaModule.getOpens();
case EXPORTS -> javaModule.getExports();
};
}
LOG.error("Unexpected role " + role);
return Collections.emptyList();
}

@Nonnull
private String getKeyword() {
switch (myRole) {
case OPENS:
return PsiKeyword.OPENS;
case EXPORTS:
return PsiKeyword.EXPORTS;
@Nonnull
private String getKeyword() {
return switch (myRole) {
case OPENS -> PsiKeyword.OPENS;
case EXPORTS -> PsiKeyword.EXPORTS;
};
}
LOG.error("Unexpected role " + myRole);
return "";
}
}
Loading
Loading