From 846d7783a65d338e82430441a31716f892435c49 Mon Sep 17 00:00:00 2001 From: UNV Date: Sun, 5 Apr 2026 11:56:13 +0300 Subject: [PATCH] Updating PascalImportOptimizer after changes in platform. Refactoring. --- .../pascal/lang/PascalImportOptimizer.java | 175 +++++++++++------- 1 file changed, 107 insertions(+), 68 deletions(-) diff --git a/plugin/src/main/java/com/siberika/idea/pascal/lang/PascalImportOptimizer.java b/plugin/src/main/java/com/siberika/idea/pascal/lang/PascalImportOptimizer.java index ddfdb6c0..bab40df8 100644 --- a/plugin/src/main/java/com/siberika/idea/pascal/lang/PascalImportOptimizer.java +++ b/plugin/src/main/java/com/siberika/idea/pascal/lang/PascalImportOptimizer.java @@ -1,6 +1,5 @@ package com.siberika.idea.pascal.lang; -import com.siberika.idea.pascal.PascalBundle; import com.siberika.idea.pascal.PascalFileType; import com.siberika.idea.pascal.PascalLanguage; import com.siberika.idea.pascal.lang.context.ContextUtil; @@ -10,6 +9,7 @@ import com.siberika.idea.pascal.util.DocUtil; import com.siberika.idea.pascal.util.ModuleUtil; import com.siberika.idea.pascal.util.PsiUtil; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; import consulo.document.Document; import consulo.document.util.TextRange; @@ -21,26 +21,25 @@ import consulo.language.psi.PsiFile; import consulo.language.psi.PsiManager; import consulo.language.psi.util.PsiTreeUtil; -import consulo.language.util.ModuleUtilCore; +import consulo.localize.LocalizeValue; import consulo.logging.Logger; import consulo.module.Module; +import consulo.object.pascal.localize.ObjectPascalLocalize; import consulo.project.Project; import consulo.util.collection.SmartList; import consulo.util.lang.Pair; import jakarta.annotation.Nonnull; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.regex.Pattern; /** - * Author: George Bakhtadze - * Date: 17/12/2015 + * @author George Bakhtadze + * @since 2015-12-17 */ @ExtensionImpl public class PascalImportOptimizer implements ImportOptimizer { - private static final Logger LOG = Logger.getInstance(PascalImportOptimizer.class); private static final Pattern RE_UNITNAME_PREFIX = Pattern.compile("[{}!]"); @@ -60,14 +59,17 @@ public static UsedUnitStatus getUsedUnitStatus(PascalQualifiedIdent usedUnitName } PascalModule pasModule = PsiUtil.getElementPasModule(usedUnitName); if ((pasModule != null)) { - Pair, List> idents = pasModule.getIdentsFrom(usedUnitName.getName(), true, ModuleUtil.retrieveUnitNamespaces(module, project)); + Pair, List> idents = + pasModule.getIdentsFrom(usedUnitName.getName(), true, ModuleUtil.retrieveUnitNamespaces(module, project)); if (ContextUtil.belongsToInterface(usedUnitName)) { if (idents.getFirst().size() + idents.getSecond().size() == 0) { res = UsedUnitStatus.UNUSED; - } else if (idents.getFirst().size() == 0) { + } + else if (idents.getFirst().size() == 0) { res = UsedUnitStatus.USED_IN_IMPL; } - } else if (idents.getSecond().size() == 0) { + } + else if (idents.getSecond().size() == 0) { res = UsedUnitStatus.UNUSED; } } @@ -85,17 +87,22 @@ private static boolean supportsOptimization(PsiFile file) { @NotNull @Override + @RequiredReadAction public Runnable processFile(final PsiFile file) { return doProcess(file); } + @RequiredReadAction public static Runnable doProcess(final PsiFile file) { - final Map units = new TreeMap(new ByOffsetComparator()); + Map units = new TreeMap<>(new ByOffsetComparator<>()); Collection usesClauses = PsiTreeUtil.findChildrenOfType(file, PasUsesClause.class); - Module module = ModuleUtilCore.findModuleForPsiElement(file); + Module module = file.getModule(); //noinspection unchecked - for (PascalQualifiedIdent usedUnitName : PsiUtil.findChildrenOfAnyType(PsiUtil.getElementPasModule(file), PascalQualifiedIdent.class)) { + for (PascalQualifiedIdent usedUnitName : PsiUtil.findChildrenOfAnyType( + PsiUtil.getElementPasModule(file), + PascalQualifiedIdent.class + )) { if (PsiUtil.isUsedUnitName(usedUnitName)) { UsedUnitStatus status = PascalImportOptimizer.getUsedUnitStatus(usedUnitName, module); if (status != UsedUnitStatus.USED) { @@ -109,7 +116,8 @@ public static Runnable doProcess(final PsiFile file) { for (PasUsesClause usesClause : usesClauses) { if (ContextUtil.belongsToInterface(usesClause)) { usesIntf = usesClause; - } else { + } + else { usesImpl = usesClause; } } @@ -119,13 +127,11 @@ public static Runnable doProcess(final PsiFile file) { final Document doc = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); return new CollectingInfoRunnable() { + private LocalizeValue myStatus; - private String status; - - @Nullable @Override - public String getUserNotificationInfo() { - return status; + public LocalizeValue getUserNotificationInfo() { + return myStatus; } @Override @@ -136,13 +142,13 @@ public void run() { try { int remIntf = usesInterface != null ? usesInterface.getNamespaceIdentList().size() : 0; int remImpl = usesImplementation != null ? usesImplementation.getNamespaceIdentList().size() : 0; - List toRemoveIntf = new SmartList(); - List toRemoveImpl = new SmartList(); + List toRemoveIntf = new SmartList<>(); + List toRemoveImpl = new SmartList<>(); List unitRangesIntf = getUnitRanges(usesInterface); List unitRangesImpl = getUnitRanges(usesImplementation); - List toMove = new SmartList(); - for (Map.Entry unit : units.entrySet()) { // perform add operations - if (unit.getValue() == UsedUnitStatus.USED_IN_IMPL) { // move from interface to implementation + List toMove = new SmartList<>(); + for (Map.Entry unit : units.entrySet()) { // perform add operations + if (unit.getValue() == UsedUnitStatus.USED_IN_IMPL) { // move from interface to implementation toMove.add(unit.getKey().getName()); remImpl++; } @@ -152,45 +158,61 @@ public void run() { unitRangesImpl.add(addedRange); } int unknown = 0; - for (Map.Entry unit : units.entrySet()) { // collect all removal ranges - if (unit.getValue() == UsedUnitStatus.USED_IN_IMPL) { // remove due to moving to implementation + for (Map.Entry unit : units.entrySet()) { // collect all removal ranges + if (unit.getValue() == UsedUnitStatus.USED_IN_IMPL) { // remove due to moving to implementation TextRange range = removeUnitFromSection(unit.getKey(), usesInterface, unitRangesIntf, remIntf); if (range != null) { toRemoveIntf.add(range); remIntf--; } - } else if (unit.getValue() == UsedUnitStatus.UNUSED) { + } + else if (unit.getValue() == UsedUnitStatus.UNUSED) { TextRange range = removeUnitFromSection(unit.getKey(), usesInterface, unitRangesIntf, remIntf); if (range != null) { remIntf--; toRemoveIntf.add(range); - } else { + } + else { range = removeUnitFromSection(unit.getKey(), usesImplementation, unitRangesImpl, remImpl); if (range != null) { remImpl--; toRemoveImpl.add(range); } } - } else if (unit.getValue() == UsedUnitStatus.UNKNOWN) { + } + else if (unit.getValue() == UsedUnitStatus.UNKNOWN) { unknown++; } } - removeUnits(doc, usesImplementation, toRemoveImpl, remImpl); // remove implementation uses clause before other modifications + removeUnits( + doc, + usesImplementation, + toRemoveImpl, + remImpl + ); // remove implementation uses clause before other modifications removeUnits(doc, usesInterface, toRemoveIntf, remIntf); PsiDocumentManager.getInstance(file.getProject()).commitDocument(doc); - status = String.format("%d units moved to implementation, %d removed, %d unknown", - toMove.size(), toRemoveImpl.size() + toRemoveIntf.size() - toMove.size(), unknown); - } catch (Exception e) { + myStatus = LocalizeValue.localizeTODO(String.format( + "%d units moved to implementation, %d removed, %d unknown", + toMove.size(), toRemoveImpl.size() + toRemoveIntf.size() - toMove.size(), unknown + )); + } + catch (Exception e) { LOG.info("Error", e); } } }; } + @RequiredReadAction private static void removeUnits(Document doc, PasUsesClause clause, List toRemove, int remaining) { - if ((clause != null) && (0 == remaining)) { - doc.deleteString(clause.getTextRange().getStartOffset(), DocUtil.expandRangeEnd(doc, clause.getTextRange().getEndOffset(), DocUtil.RE_LF)); - } else { + if (clause != null && 0 == remaining) { + doc.deleteString( + clause.getTextRange().getStartOffset(), + DocUtil.expandRangeEnd(doc, clause.getTextRange().getEndOffset(), DocUtil.RE_LF) + ); + } + else { Collections.sort(toRemove, new ByOffsetComparator2()); for (TextRange textRange : toRemove) { doc.deleteString(textRange.getStartOffset(), textRange.getEndOffset()); @@ -198,46 +220,54 @@ private static void removeUnits(Document doc, PasUsesClause clause, List getUnitRanges(PasUsesClause usesClause) { if (null == usesClause) { - return new SmartList(); + return new SmartList<>(); } - List res = new ArrayList(usesClause.getNamespaceIdentList().size()); + List res = new ArrayList<>(usesClause.getNamespaceIdentList().size()); for (PascalQualifiedIdent ident : usesClause.getNamespaceIdentList()) { res.add(ident.getTextRange()); } return res; } + @RequiredReadAction public static TextRange addUnitToSection(final PasModule module, List names, boolean toInterface) { - if ((null == module) || (names.isEmpty())) { + if (null == module || names.isEmpty()) { return null; } - assert (!toInterface || (module.getModuleType() == PascalModule.ModuleType.UNIT)); + assert (!toInterface || module.getModuleType() == PascalModule.ModuleType.UNIT); final PasUsesClause uses; if (toInterface) { uses = PsiTreeUtil.findChildOfType(PsiUtil.getModuleInterfaceSection(module), PasUsesClause.class); - } else { - uses = PsiTreeUtil.findChildOfType((module.getModuleType() == PascalModule.ModuleType.UNIT) ? PsiUtil.getModuleImplementationSection(module) : module, PasUsesClause.class); + } + else { + uses = PsiTreeUtil.findChildOfType( + module.getModuleType() == PascalModule.ModuleType.UNIT ? PsiUtil.getModuleImplementationSection(module) : module, + PasUsesClause.class + ); } int offs = 0; String content = String.join(", ", names); if (uses != null) { offs = uses.getTextRange().getEndOffset() - 1; content = ",\n" + content + ";"; - } else { + } + else { content = "\n\nuses\n" + content + ";\n"; - @SuppressWarnings("unchecked") PsiElement prev = PsiTreeUtil.findChildOfAnyType(module, PasProgramModuleHead.class, PasLibraryModuleHead.class, PasPackageModuleHead.class); + @SuppressWarnings("unchecked") PsiElement prev = + PsiTreeUtil.findChildOfAnyType(module, PasProgramModuleHead.class, PasLibraryModuleHead.class, PasPackageModuleHead.class); if (calcOffset(prev) >= 0) { offs = calcOffset(prev); - } else { - if (toInterface) { - PsiElement section = PsiUtil.getModuleInterfaceSection(module); - offs = section != null ? section.getTextRange().getStartOffset() + "interface".length() : offs; - } else { - PsiElement section = PsiUtil.getModuleImplementationSection(module); - offs = section != module ? section.getTextRange().getStartOffset() + "implementation".length(): offs; - } + } + else if (toInterface) { + PsiElement section = PsiUtil.getModuleInterfaceSection(module); + offs = section != null ? section.getTextRange().getStartOffset() + "interface".length() : offs; + } + else { + PsiElement section = PsiUtil.getModuleImplementationSection(module); + offs = section != module ? section.getTextRange().getStartOffset() + "implementation".length() : offs; } } final PsiFile file = module.getContainingFile(); @@ -246,26 +276,38 @@ public static TextRange addUnitToSection(final PasModule module, List na DocUtil.adjustDocument(doc, offs, content); PsiDocumentManager.getInstance(module.getProject()).commitDocument(doc); } - DocUtil.runCommandLaterInWriteAction(module.getProject(), PascalBundle.message("action.reformat"), new Runnable() { - @Override - public void run() { + DocUtil.runCommandLaterInWriteAction( + module.getProject(), + ObjectPascalLocalize.actionReformat().get(), + () -> { for (PasUsesClause usesClause : PsiTreeUtil.findChildrenOfType(module, PasUsesClause.class)) { PsiManager manager = usesClause.getManager(); if (manager != null) { - CodeStyleManager.getInstance(manager).reformatRange(file, usesClause.getTextRange().getStartOffset(), usesClause.getTextRange().getEndOffset(), true); + CodeStyleManager.getInstance(manager).reformatRange( + file, + usesClause.getTextRange().getStartOffset(), + usesClause.getTextRange().getEndOffset(), + true + ); } } } - }); + ); return TextRange.create(offs + 2, offs + content.length()); } + @RequiredReadAction private static int calcOffset(PsiElement prev) { return prev != null ? prev.getTextRange().getEndOffset() : -1; } - public static TextRange removeUnitFromSection(PascalQualifiedIdent usedUnit, PasUsesClause uses, List unitRanges, int remaining) { - if ((0 == remaining) || (null == uses) || (null == uses.getContainingFile())) { + public static TextRange removeUnitFromSection( + PascalQualifiedIdent usedUnit, + PasUsesClause uses, + List unitRanges, + int remaining + ) { + if (0 == remaining || null == uses || null == uses.getContainingFile()) { return null; } Document doc = PsiDocumentManager.getInstance(uses.getProject()).getDocument(uses.getContainingFile()); @@ -274,21 +316,19 @@ public static TextRange removeUnitFromSection(PascalQualifiedIdent usedUnit, Pas return null; } int start = DocUtil.expandRangeStart(doc, unitRanges.get(index).getStartOffset(), RE_UNITNAME_PREFIX); - int end = unitRanges.get(index).getEndOffset(); // Single + int end = unitRanges.get(index).getEndOffset(); // Single if (index > 0) { - if (index == remaining - 1) { // Right + if (index == remaining - 1) { // Right start = unitRanges.get(index - 1).getEndOffset(); - } else { - if (index < remaining - 1) { // Middle - end = DocUtil.expandRangeStart(doc, unitRanges.get(index + 1).getStartOffset(), RE_UNITNAME_PREFIX); - } } - } else { - if (index < unitRanges.size() - 1) { // Left + else if (index < remaining - 1) { // Middle end = DocUtil.expandRangeStart(doc, unitRanges.get(index + 1).getStartOffset(), RE_UNITNAME_PREFIX); } } + else if (index < unitRanges.size() - 1) { // Left + end = DocUtil.expandRangeStart(doc, unitRanges.get(index + 1).getStartOffset(), RE_UNITNAME_PREFIX); + } return TextRange.create(start, end); } @@ -312,6 +352,7 @@ public Language getLanguage() { private static class ByOffsetComparator implements Comparator { @Override + @RequiredReadAction public int compare(PsiElement o1, PsiElement o2) { return o2.getTextRange().getStartOffset() - o1.getTextRange().getStartOffset(); } @@ -323,6 +364,4 @@ public int compare(TextRange o1, TextRange o2) { return o2.getStartOffset() - o1.getStartOffset(); } } - - }