use of com.intellij.refactoring.util.NonCodeUsageInfo in project intellij-community by JetBrains.
the class MoveFilesOrDirectoriesProcessor method retargetUsages.
protected void retargetUsages(UsageInfo[] usages, Map<PsiElement, PsiElement> oldToNewMap) {
final List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<>();
for (UsageInfo usageInfo : usages) {
if (usageInfo instanceof MyUsageInfo) {
final MyUsageInfo info = (MyUsageInfo) usageInfo;
final PsiElement element = myElementsToMove[info.myIndex];
if (info.getReference() instanceof FileReference || info.getReference() instanceof PsiDynaReference) {
final PsiElement usageElement = info.getElement();
if (usageElement != null) {
final PsiFile usageFile = usageElement.getContainingFile();
final PsiFile psiFile = usageFile.getViewProvider().getPsi(usageFile.getViewProvider().getBaseLanguage());
if (psiFile != null && psiFile.equals(element)) {
// already processed in MoveFilesOrDirectoriesUtil.doMoveFile
continue;
}
}
}
final PsiElement refElement = info.myReference.getElement();
if (refElement != null && refElement.isValid()) {
info.myReference.bindToElement(element);
}
} else if (usageInfo instanceof NonCodeUsageInfo) {
nonCodeUsages.add((NonCodeUsageInfo) usageInfo);
}
}
for (PsiFile movedFile : myFoundUsages.keySet()) {
MoveFileHandler.forElement(movedFile).retargetUsages(myFoundUsages.get(movedFile), oldToNewMap);
}
myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
}
use of com.intellij.refactoring.util.NonCodeUsageInfo in project intellij-community by JetBrains.
the class CommonMoveUtil method retargetUsages.
public static NonCodeUsageInfo[] retargetUsages(final UsageInfo[] usages, final Map<PsiElement, PsiElement> oldToNewElementsMapping) throws IncorrectOperationException {
Arrays.sort(usages, (o1, o2) -> {
final VirtualFile file1 = o1.getVirtualFile();
final VirtualFile file2 = o2.getVirtualFile();
if (Comparing.equal(file1, file2)) {
final ProperTextRange rangeInElement1 = o1.getRangeInElement();
final ProperTextRange rangeInElement2 = o2.getRangeInElement();
if (rangeInElement1 != null && rangeInElement2 != null) {
return rangeInElement2.getStartOffset() - rangeInElement1.getStartOffset();
}
return 0;
}
if (file1 == null)
return -1;
if (file2 == null)
return 1;
return Comparing.compare(file1.getPath(), file2.getPath());
});
List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<>();
for (UsageInfo usage : usages) {
if (usage instanceof NonCodeUsageInfo) {
nonCodeUsages.add((NonCodeUsageInfo) usage);
} else if (usage instanceof MoveRenameUsageInfo) {
final MoveRenameUsageInfo moveRenameUsage = (MoveRenameUsageInfo) usage;
final PsiElement oldElement = moveRenameUsage.getReferencedElement();
final PsiElement newElement = oldToNewElementsMapping.get(oldElement);
LOG.assertTrue(newElement != null, oldElement);
final PsiReference reference = moveRenameUsage.getReference();
if (reference != null) {
try {
reference.bindToElement(newElement);
} catch (IncorrectOperationException e) {
//
}
}
}
}
return nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
}
use of com.intellij.refactoring.util.NonCodeUsageInfo in project intellij-community by JetBrains.
the class MoveDirectoryWithClassesProcessor method performRefactoring.
@Override
public void performRefactoring(@NotNull UsageInfo[] usages) {
//try to create all directories beforehand
try {
//top level directories should be created even if they are empty
for (PsiDirectory directory : myDirectories) {
getResultDirectory(directory).findOrCreateTargetDirectory();
}
for (PsiDirectory directory : myNestedDirsToMove.keySet()) {
myNestedDirsToMove.get(directory).findOrCreateTargetDirectory();
}
for (PsiFile psiFile : myFilesToMove.keySet()) {
myFilesToMove.get(psiFile).findOrCreateTargetDirectory();
}
DumbService.getInstance(myProject).completeJustSubmittedTasks();
final List<PsiFile> movedFiles = new ArrayList<>();
final Map<PsiElement, PsiElement> oldToNewElementsMapping = new HashMap<>();
for (PsiFile psiFile : myFilesToMove.keySet()) {
for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
helper.beforeMove(psiFile);
}
final RefactoringElementListener listener = getTransaction().getElementListener(psiFile);
final PsiDirectory moveDestination = myFilesToMove.get(psiFile).getTargetDirectory();
for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
boolean processed = helper.move(psiFile, moveDestination, oldToNewElementsMapping, movedFiles, listener);
if (processed) {
break;
}
}
}
for (PsiElement newElement : oldToNewElementsMapping.values()) {
for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
helper.afterMove(newElement);
}
}
// fix references in moved files to outer files
for (PsiFile movedFile : movedFiles) {
MoveFileHandler.forElement(movedFile).updateMovedFile(movedFile);
FileReferenceContextUtil.decodeFileReferences(movedFile);
}
myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping);
for (MoveDirectoryWithClassesHelper helper : MoveDirectoryWithClassesHelper.findAll()) {
helper.postProcessUsages(usages, dir -> getResultDirectory(dir).findOrCreateTargetDirectory());
}
for (PsiDirectory directory : myDirectories) {
final TargetDirectoryWrapper wrapper = myNestedDirsToMove.get(directory);
final PsiDirectory targetDirectory = wrapper.getTargetDirectory();
if (targetDirectory == null || !PsiTreeUtil.isAncestor(directory, targetDirectory, false)) {
directory.delete();
}
}
} catch (IncorrectOperationException e) {
myNonCodeUsages = new NonCodeUsageInfo[0];
RefactoringUIUtil.processIncorrectOperation(myProject, e);
}
}
use of com.intellij.refactoring.util.NonCodeUsageInfo in project intellij-community by JetBrains.
the class UsageViewUtil method removeDuplicatedUsages.
@NotNull
public static UsageInfo[] removeDuplicatedUsages(@NotNull UsageInfo[] usages) {
Set<UsageInfo> set = new LinkedHashSet<>(Arrays.asList(usages));
// Replace duplicates of move rename usage infos in injections from non code usages of master files
String newTextInNonCodeUsage = null;
for (UsageInfo usage : usages) {
if (!(usage instanceof NonCodeUsageInfo))
continue;
newTextInNonCodeUsage = ((NonCodeUsageInfo) usage).newText;
break;
}
if (newTextInNonCodeUsage != null) {
for (UsageInfo usage : usages) {
if (!(usage instanceof MoveRenameUsageInfo))
continue;
PsiFile file = usage.getFile();
if (file != null) {
PsiElement context = InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
if (context != null) {
PsiElement usageElement = usage.getElement();
if (usageElement == null)
continue;
PsiReference psiReference = usage.getReference();
if (psiReference == null)
continue;
int injectionOffsetInMasterFile = InjectedLanguageManager.getInstance(usageElement.getProject()).injectedToHost(usageElement, usageElement.getTextOffset());
TextRange rangeInElement = usage.getRangeInElement();
assert rangeInElement != null : usage;
TextRange range = rangeInElement.shiftRight(injectionOffsetInMasterFile);
PsiFile containingFile = context.getContainingFile();
//move package to another package
if (containingFile == null)
continue;
set.remove(NonCodeUsageInfo.create(containingFile, range.getStartOffset(), range.getEndOffset(), ((MoveRenameUsageInfo) usage).getReferencedElement(), newTextInNonCodeUsage));
}
}
}
}
return set.toArray(new UsageInfo[set.size()]);
}
use of com.intellij.refactoring.util.NonCodeUsageInfo in project intellij-community by JetBrains.
the class MoveInnerProcessor method performRefactoring.
protected void performRefactoring(@NotNull final UsageInfo[] usages) {
final PsiManager manager = PsiManager.getInstance(myProject);
final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
final RefactoringElementListener elementListener = getTransaction().getElementListener(myInnerClass);
try {
PsiField field = null;
if (myParameterNameOuterClass != null) {
// pass outer as a parameter
field = factory.createField(myFieldNameOuterClass, factory.createType(myOuterClass));
field = addOuterField(field);
myInnerClass = field.getContainingClass();
addFieldInitializationToConstructors(myInnerClass, field, myParameterNameOuterClass);
}
ChangeContextUtil.encodeContextInfo(myInnerClass, false);
myInnerClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myInnerClass);
final MoveInnerOptions moveInnerOptions = new MoveInnerOptions(myInnerClass, myOuterClass, myTargetContainer, myNewClassName);
final MoveInnerHandler handler = MoveInnerHandler.EP_NAME.forLanguage(myInnerClass.getLanguage());
final PsiClass newClass;
try {
newClass = handler.copyClass(moveInnerOptions);
} catch (IncorrectOperationException e) {
RefactoringUIUtil.processIncorrectOperation(myProject, e);
return;
}
// replace references in a new class to old inner class with references to itself
for (PsiReference ref : ReferencesSearch.search(myInnerClass, new LocalSearchScope(newClass), true)) {
PsiElement element = ref.getElement();
if (element.getParent() instanceof PsiJavaCodeReferenceElement) {
PsiJavaCodeReferenceElement parentRef = (PsiJavaCodeReferenceElement) element.getParent();
PsiElement parentRefElement = parentRef.resolve();
if (parentRefElement instanceof PsiClass) {
// reference to inner class inside our inner
final PsiReferenceList referenceList = PsiTreeUtil.getTopmostParentOfType(parentRef, PsiReferenceList.class);
if (referenceList == null || referenceList.getParent() != newClass) {
parentRef.getQualifier().delete();
continue;
}
}
}
ref.bindToElement(newClass);
}
List<PsiReference> referencesToRebind = new ArrayList<>();
for (UsageInfo usage : usages) {
if (usage.isNonCodeUsage)
continue;
PsiElement refElement = usage.getElement();
PsiReference[] references = refElement.getReferences();
for (PsiReference reference : references) {
if (reference.isReferenceTo(myInnerClass)) {
referencesToRebind.add(reference);
}
}
}
myInnerClass.delete();
// correct references in usages
for (UsageInfo usage : usages) {
// should pass outer as parameter
if (usage.isNonCodeUsage || myParameterNameOuterClass == null)
continue;
MoveInnerClassUsagesHandler usagesHandler = MoveInnerClassUsagesHandler.EP_NAME.forLanguage(usage.getElement().getLanguage());
if (usagesHandler != null) {
usagesHandler.correctInnerClassUsage(usage, myOuterClass);
}
}
for (PsiReference reference : referencesToRebind) {
reference.bindToElement(newClass);
}
for (UsageInfo usage : usages) {
final PsiElement element = usage.getElement();
final PsiElement parent = element != null ? element.getParent() : null;
if (parent instanceof PsiNewExpression) {
final PsiMethod resolveConstructor = ((PsiNewExpression) parent).resolveConstructor();
for (PsiMethod method : newClass.getConstructors()) {
if (resolveConstructor == method) {
final PsiElement place = usage.getElement();
if (place != null) {
VisibilityUtil.escalateVisibility(method, place);
}
break;
}
}
}
}
if (field != null) {
final PsiExpression paramAccessExpression = factory.createExpressionFromText(myParameterNameOuterClass, null);
for (final PsiMethod constructor : newClass.getConstructors()) {
final PsiStatement[] statements = constructor.getBody().getStatements();
if (statements.length > 0) {
if (statements[0] instanceof PsiExpressionStatement) {
PsiExpression expression = ((PsiExpressionStatement) statements[0]).getExpression();
if (expression instanceof PsiMethodCallExpression) {
@NonNls String text = ((PsiMethodCallExpression) expression).getMethodExpression().getText();
if ("this".equals(text) || "super".equals(text)) {
ChangeContextUtil.decodeContextInfo(expression, myOuterClass, paramAccessExpression);
}
}
}
}
}
PsiExpression accessExpression = factory.createExpressionFromText(myFieldNameOuterClass, null);
ChangeContextUtil.decodeContextInfo(newClass, myOuterClass, accessExpression);
} else {
ChangeContextUtil.decodeContextInfo(newClass, null, null);
}
if (myOpenInEditor) {
EditorHelper.openInEditor(newClass);
}
if (myMoveCallback != null) {
myMoveCallback.refactoringCompleted();
}
elementListener.elementMoved(newClass);
List<NonCodeUsageInfo> nonCodeUsages = new ArrayList<>();
for (UsageInfo usage : usages) {
if (usage instanceof NonCodeUsageInfo) {
nonCodeUsages.add((NonCodeUsageInfo) usage);
}
}
myNonCodeUsages = nonCodeUsages.toArray(new NonCodeUsageInfo[nonCodeUsages.size()]);
} catch (IncorrectOperationException e) {
LOG.error(e);
}
}
Aggregations