@Nullable private static String getCannotRefactorMessage(PsiMember member) { if (member == null) { return RefactoringBundle.message("locate.caret.inside.a.method"); } if (member instanceof PsiMethod) { if (((PsiMethod) member).isConstructor()) { return RefactoringBundle.message("replace.with.method.call.does.not.work.for.constructors"); } final PsiCodeBlock body = ((PsiMethod) member).getBody(); if (body == null) { return RefactoringBundle.message("method.does.not.have.a.body", member.getName()); } final PsiStatement[] statements = body.getStatements(); if (statements.length == 0) { return RefactoringBundle.message("method.has.an.empty.body", member.getName()); } } else if (member instanceof PsiField) { final PsiField field = (PsiField) member; if (field.getInitializer() == null) { return "Field " + member.getName() + " doesn't have initializer"; } final PsiClass containingClass = field.getContainingClass(); if (!field.hasModifierProperty(PsiModifier.FINAL) || !field.hasModifierProperty(PsiModifier.STATIC) || containingClass == null || containingClass.getQualifiedName() == null) { return "Replace Duplicates works with constants only"; } } else { return "Caret should be inside method or constant"; } return null; }
@NotNull private Field fieldToField(@NotNull PsiField field, PsiClass psiClass) { Set<String> modifiers = modifiersListToModifiersSet(field.getModifierList()); if (field instanceof PsiEnumConstant) // TODO: remove instanceof { return new EnumConstant( new IdentifierImpl(field.getName()), // TODO modifiers, typeToType(field.getType()), elementToElement(((PsiEnumConstant) field).getArgumentList())); } return new Field( new IdentifierImpl(field.getName()), // TODO modifiers, typeToType(field.getType(), ConverterUtil.isAnnotatedAsNotNull(field.getModifierList())), createSureCallOnlyForChain(field.getInitializer(), field.getType()), // TODO: add modifiers countWritingAccesses(field, psiClass)); }
public static Set<PsiField> getNonInitializedFields(PsiElement element) { final PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class); final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class, true, PsiClass.class); if (statement == null || method == null || !method.isConstructor()) { return Collections.emptySet(); } PsiElement parent = element.getParent(); while (parent != statement) { PsiElement next = parent.getParent(); if (next instanceof PsiAssignmentExpression && parent == ((PsiAssignmentExpression) next).getLExpression()) { return Collections.emptySet(); } if (parent instanceof PsiReferenceExpression && next instanceof PsiExpressionStatement) { return Collections.emptySet(); } parent = next; } final Set<PsiField> fields = new HashSet<PsiField>(); final PsiClass containingClass = method.getContainingClass(); assert containingClass != null; for (PsiField field : containingClass.getFields()) { if (!field.hasModifierProperty(PsiModifier.STATIC) && field.getInitializer() == null && !isInitializedImplicitly(field)) { fields.add(field); } } method.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { if (expression.getTextRange().getStartOffset() < statement.getTextRange().getStartOffset()) { final PsiExpression lExpression = expression.getLExpression(); if (lExpression instanceof PsiReferenceExpression) { //noinspection SuspiciousMethodCalls fields.remove(((PsiReferenceExpression) lExpression).resolve()); } } super.visitAssignmentExpression(expression); } @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { if (expression.getTextRange().getStartOffset() < statement.getTextRange().getStartOffset()) { final PsiReferenceExpression methodExpression = expression.getMethodExpression(); if (methodExpression.textMatches("this")) { fields.clear(); } } super.visitMethodCallExpression(expression); } }); return fields; }
protected void performRefactoring(@NotNull UsageInfo[] usageInfos) { final PsiClass psiClass = buildClass(); if (psiClass == null) return; if (delegationRequired) { buildDelegate(); } myExtractEnumProcessor.performEnumConstantTypeMigration(usageInfos); final Set<PsiMember> members = new HashSet<PsiMember>(); for (PsiMethod method : methods) { final PsiMethod member = psiClass.findMethodBySignature(method, false); if (member != null) { members.add(member); } } for (PsiField field : fields) { final PsiField member = psiClass.findFieldByName(field.getName(), false); if (member != null) { members.add(member); final PsiExpression initializer = member.getInitializer(); if (initializer != null) { final boolean[] moveInitializerToConstructor = new boolean[1]; initializer.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiField && !members.contains(resolved)) { moveInitializerToConstructor[0] = true; } } }); if (moveInitializerToConstructor[0]) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiMethod[] constructors = psiClass.getConstructors(); if (constructors.length == 0) { final PsiMethod constructor = (PsiMethod) elementFactory.createConstructor().setName(psiClass.getName()); constructors = new PsiMethod[] {(PsiMethod) psiClass.add(constructor)}; } for (PsiMethod constructor : constructors) { MoveInstanceMembersUtil.moveInitializerToConstructor( elementFactory, constructor, member); } } } } } if (myGenerateAccessors) { final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4SourceClass(); for (PsiField field : visitor.getFieldsNeedingGetter()) { sourceClass.add(GenerateMembersUtil.generateGetterPrototype(field)); } for (PsiField field : visitor.getFieldsNeedingSetter()) { sourceClass.add(GenerateMembersUtil.generateSetterPrototype(field)); } } super.performRefactoring(usageInfos); if (myNewVisibility == null) return; for (PsiMember member : members) { VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usageInfos), member, myNewVisibility); } }