public void invoke( @NotNull Project project, Editor editor, PsiFile file, DataContext dataContext) { editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); final int offset = TargetElementUtil.adjustOffset( file, editor.getDocument(), editor.getCaretModel().getOffset()); final PsiElement element = file.findElementAt(offset); PsiTypeElement typeElement = PsiTreeUtil.getParentOfType(element, PsiTypeElement.class); while (typeElement != null) { final PsiElement parent = typeElement.getParent(); PsiElement[] toMigrate = null; if (parent instanceof PsiVariable) { toMigrate = extractReferencedVariables(typeElement); } else if ((parent instanceof PsiMember && !(parent instanceof PsiClass)) || isClassArgument(parent)) { toMigrate = new PsiElement[] {parent}; } if (toMigrate != null && toMigrate.length > 0) { invoke(project, toMigrate, null, null, editor); return; } typeElement = PsiTreeUtil.getParentOfType(parent, PsiTypeElement.class, false); } CommonRefactoringUtil.showErrorHint( project, editor, "The caret should be positioned on type of field, variable, method or method parameter to be refactored", REFACTORING_NAME, "refactoring.migrateType"); }
@NotNull private static PsiElement[] extractReferencedVariables(@NotNull PsiTypeElement typeElement) { final PsiElement parent = typeElement.getParent(); if (parent instanceof PsiVariable) { if (parent instanceof PsiField) { PsiField aField = (PsiField) parent; List<PsiField> fields = new ArrayList<>(); while (true) { fields.add(aField); aField = PsiTreeUtil.getNextSiblingOfType(aField, PsiField.class); if (aField == null || aField.getTypeElement() != typeElement) { return fields.toArray(new PsiElement[fields.size()]); } } } else if (parent instanceof PsiLocalVariable) { final PsiDeclarationStatement declaration = PsiTreeUtil.getParentOfType(parent, PsiDeclarationStatement.class); if (declaration != null) { return Arrays.stream(declaration.getDeclaredElements()) .filter(PsiVariable.class::isInstance) .toArray(PsiVariable[]::new); } } return new PsiElement[] {parent}; } else { return PsiElement.EMPTY_ARRAY; } }