use of com.intellij.refactoring.listeners.RefactoringElementListener in project intellij-community by JetBrains.
the class DynamicToolWindowWrapper method createTable.
private JScrollPane createTable(final MutableTreeNode myTreeRoot) {
ColumnInfo[] columnInfos = { new ClassColumnInfo(myColumnNames[CLASS_OR_ELEMENT_NAME_COLUMN]), new PropertyTypeColumnInfo(myColumnNames[TYPE_COLUMN]) };
myTreeTableModel = new ListTreeTableModelOnColumns(myTreeRoot, columnInfos);
myTreeTable = new MyTreeTable(myTreeTableModel);
new TreeTableSpeedSearch(myTreeTable, new Convertor<TreePath, String>() {
@Override
public String convert(TreePath o) {
final Object node = o.getLastPathComponent();
if (node instanceof DefaultMutableTreeNode) {
final Object object = ((DefaultMutableTreeNode) node).getUserObject();
if (object instanceof DNamedElement) {
return ((DNamedElement) object).getName();
}
}
return "";
}
});
DefaultActionGroup group = new DefaultActionGroup();
group.add(ActionManager.getInstance().getAction(RemoveDynamicAction.GROOVY_DYNAMIC_REMOVE));
PopupHandler.installUnknownPopupHandler(myTreeTable, group, ActionManager.getInstance());
final MyColoredTreeCellRenderer treeCellRenderer = new MyColoredTreeCellRenderer();
myTreeTable.setDefaultRenderer(String.class, new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof String) {
try {
final PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText((String) value, null);
String shortName = type.getPresentableText();
return new JLabel(shortName);
} catch (IncorrectOperationException e) {
LOG.debug("Type cannot be created", e);
}
return new JLabel(QuickfixUtil.shortenType((String) value));
}
return new JLabel();
}
});
myTreeTable.setTreeCellRenderer(treeCellRenderer);
myTreeTable.setRootVisible(false);
myTreeTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
final MyPropertyTypeCellEditor typeCellEditor = new MyPropertyTypeCellEditor();
typeCellEditor.addCellEditorListener(new CellEditorListener() {
@Override
public void editingStopped(ChangeEvent e) {
final TreeTableTree tree = getTree();
String newTypeValue = ((MyPropertyTypeCellEditor) e.getSource()).getCellEditorValue();
if (newTypeValue == null || tree == null) {
myTreeTable.editingStopped(e);
return;
}
try {
final PsiType type = JavaPsiFacade.getElementFactory(myProject).createTypeFromText(newTypeValue, null);
String canonical = type.getCanonicalText();
if (canonical != null)
newTypeValue = canonical;
} catch (IncorrectOperationException ex) {
//do nothing in case bad string is entered
}
final TreePath editingTypePath = tree.getSelectionPath();
if (editingTypePath == null)
return;
final TreePath editingClassPath = editingTypePath.getParentPath();
Object oldTypeValue = myTreeTable.getValueAt(tree.getRowForPath(editingTypePath), TYPE_COLUMN);
if (!(oldTypeValue instanceof String)) {
myTreeTable.editingStopped(e);
return;
}
final Object editingPropertyObject = myTreeTable.getValueAt(tree.getRowForPath(editingTypePath), CLASS_OR_ELEMENT_NAME_COLUMN);
final Object editingClassObject = myTreeTable.getValueAt(tree.getRowForPath(editingClassPath), CLASS_OR_ELEMENT_NAME_COLUMN);
if (!(editingPropertyObject instanceof DItemElement) || !(editingClassObject instanceof DClassElement)) {
myTreeTable.editingStopped(e);
return;
}
final DItemElement dynamicElement = (DItemElement) editingPropertyObject;
final String name = dynamicElement.getName();
final String className = ((DClassElement) editingClassObject).getName();
if (dynamicElement instanceof DPropertyElement) {
DynamicManager.getInstance(myProject).replaceDynamicPropertyType(className, name, (String) oldTypeValue, newTypeValue);
} else if (dynamicElement instanceof DMethodElement) {
final List<ParamInfo> myPairList = ((DMethodElement) dynamicElement).getPairs();
DynamicManager.getInstance(myProject).replaceDynamicMethodType(className, name, myPairList, (String) oldTypeValue, newTypeValue);
}
}
@Override
public void editingCanceled(ChangeEvent e) {
myTreeTable.editingCanceled(e);
}
});
RefactoringListenerManager.getInstance(myProject).addListenerProvider(new RefactoringElementListenerProvider() {
@Override
@Nullable
public RefactoringElementListener getListener(final PsiElement element) {
if (element instanceof PsiClass) {
final String qualifiedName = ((PsiClass) element).getQualifiedName();
return new RefactoringElementListener() {
@Override
public void elementMoved(@NotNull PsiElement newElement) {
renameElement(qualifiedName, newElement);
}
@Override
public void elementRenamed(@NotNull PsiElement newElement) {
renameElement(qualifiedName, newElement);
}
private void renameElement(String oldClassName, PsiElement newElement) {
if (newElement instanceof PsiClass) {
final String newClassName = ((PsiClass) newElement).getQualifiedName();
final DRootElement rootElement = DynamicManager.getInstance(myProject).getRootElement();
final DClassElement oldClassElement = rootElement.getClassElement(oldClassName);
final TreeNode oldClassNode = TreeUtil.findNodeWithObject((DefaultMutableTreeNode) myTreeRoot, oldClassElement);
DynamicManager.getInstance(myProject).replaceClassName(oldClassElement, newClassName);
myTreeTableModel.nodeChanged(oldClassNode);
}
}
};
}
return null;
}
});
myTreeTable.setDefaultEditor(String.class, typeCellEditor);
myTreeTable.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
final int selectionRow = myTreeTable.getTree().getLeadSelectionRow();
myTreeTable.editCellAt(selectionRow, CLASS_OR_ELEMENT_NAME_COLUMN, event);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), JComponent.WHEN_FOCUSED);
myTreeTable.registerKeyboardAction(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
final int selectionRow = myTreeTable.getTree().getLeadSelectionRow();
myTreeTable.editCellAt(selectionRow, TYPE_COLUMN, event);
}
}, KeyStroke.getKeyStroke(KeyEvent.VK_F2, InputEvent.CTRL_MASK), JComponent.WHEN_FOCUSED);
myTreeTable.getTree().setShowsRootHandles(true);
myTreeTable.getTableHeader().setReorderingAllowed(false);
myTreeTable.setPreferredScrollableViewportSize(new Dimension(300, myTreeTable.getRowHeight() * 10));
myTreeTable.getColumn(myColumnNames[CLASS_OR_ELEMENT_NAME_COLUMN]).setPreferredWidth(200);
myTreeTable.getColumn(myColumnNames[TYPE_COLUMN]).setPreferredWidth(160);
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTreeTable);
scrollPane.setPreferredSize(JBUI.size(600, 400));
return scrollPane;
}
use of com.intellij.refactoring.listeners.RefactoringElementListener in project intellij-community by JetBrains.
the class TestNGConfiguration method getRefactoringElementListener.
@Nullable
public RefactoringElementListener getRefactoringElementListener(final PsiElement element) {
if (data.TEST_OBJECT.equals(TestType.PACKAGE.getType())) {
if (!(element instanceof PsiPackage))
return null;
final RefactoringElementListener listener = RefactoringListeners.getListener((PsiPackage) element, myPackage);
return RunConfigurationExtension.wrapRefactoringElementListener(element, this, listener);
} else if (data.TEST_OBJECT.equals(TestType.CLASS.getType())) {
if (!(element instanceof PsiClass) && !(element instanceof PsiPackage))
return null;
final RefactoringElementListener listener = RefactoringListeners.getClassOrPackageListener(element, myClass);
return RunConfigurationExtension.wrapRefactoringElementListener(element, this, listener);
} else if (data.TEST_OBJECT.equals(TestType.METHOD.getType())) {
if (!(element instanceof PsiMethod)) {
final RefactoringElementListener listener = RefactoringListeners.getClassOrPackageListener(element, myClass);
return RunConfigurationExtension.wrapRefactoringElementListener(element, this, listener);
}
final PsiMethod method = (PsiMethod) element;
if (!method.getName().equals(data.getMethodName()))
return null;
if (!method.getContainingClass().equals(myClass.getPsiElement()))
return null;
class Listener extends RefactoringElementAdapter implements UndoRefactoringElementListener {
public void elementRenamedOrMoved(@NotNull final PsiElement newElement) {
data.setTestMethod(PsiLocation.fromPsiElement((PsiMethod) newElement));
}
@Override
public void undoElementMovedOrRenamed(@NotNull PsiElement newElement, @NotNull String oldQualifiedName) {
final int methodIdx = oldQualifiedName.indexOf("#") + 1;
if (methodIdx <= 0 || methodIdx >= oldQualifiedName.length())
return;
data.METHOD_NAME = oldQualifiedName.substring(methodIdx);
}
}
return RunConfigurationExtension.wrapRefactoringElementListener(element, this, new Listener());
}
return null;
}
use of com.intellij.refactoring.listeners.RefactoringElementListener in project intellij-community by JetBrains.
the class MoveFilesOrDirectoriesProcessor method performRefactoring.
@Override
protected void performRefactoring(@NotNull UsageInfo[] usages) {
try {
final List<PsiFile> movedFiles = new ArrayList<>();
final Map<PsiElement, PsiElement> oldToNewMap = new HashMap<>();
for (final PsiElement element : myElementsToMove) {
final RefactoringElementListener elementListener = getTransaction().getElementListener(element);
if (element instanceof PsiDirectory) {
MoveFilesOrDirectoriesUtil.doMoveDirectory((PsiDirectory) element, myNewParent);
for (PsiElement psiElement : element.getChildren()) {
processDirectoryFiles(movedFiles, oldToNewMap, psiElement);
}
} else if (element instanceof PsiFile) {
final PsiFile movedFile = (PsiFile) element;
if (mySearchForReferences)
FileReferenceContextUtil.encodeFileReferences(element);
MoveFileHandler.forElement(movedFile).prepareMovedFile(movedFile, myNewParent, oldToNewMap);
PsiFile moving = myNewParent.findFile(movedFile.getName());
if (moving == null) {
MoveFilesOrDirectoriesUtil.doMoveFile(movedFile, myNewParent);
}
moving = myNewParent.findFile(movedFile.getName());
movedFiles.add(moving);
}
elementListener.elementMoved(element);
}
// sort by offset descending to process correctly several usages in one PsiElement [IDEADEV-33013]
CommonRefactoringUtil.sortDepthFirstRightLeftOrder(usages);
DumbService.getInstance(myProject).completeJustSubmittedTasks();
// fix references in moved files to outer files
for (PsiFile movedFile : movedFiles) {
MoveFileHandler.forElement(movedFile).updateMovedFile(movedFile);
if (mySearchForReferences)
FileReferenceContextUtil.decodeFileReferences(movedFile);
}
retargetUsages(usages, oldToNewMap);
if (MoveFilesOrDirectoriesDialog.isOpenInEditor()) {
EditorHelper.openFilesInEditor(movedFiles.toArray(new PsiFile[movedFiles.size()]));
}
if (myMoveCallback != null) {
myMoveCallback.refactoringCompleted();
}
} catch (IncorrectOperationException e) {
final String message = e.getMessage();
final int index = message != null ? message.indexOf("java.io.IOException") : -1;
if (index >= 0 && message != null) {
ApplicationManager.getApplication().invokeLater(() -> {
String cause = message.substring(index + "java.io.IOException".length());
Messages.showMessageDialog(myProject, cause, RefactoringBundle.message("error.title"), Messages.getErrorIcon());
});
} else {
LOG.error(e);
}
}
}
use of com.intellij.refactoring.listeners.RefactoringElementListener 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.listeners.RefactoringElementListener 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