List<InnerClassMethod> () { ArrayList<InnerClassMethod> result = new ArrayList<>(); // find all neccessary constructors if (!myBaseClass.isInterface()) { PsiMethod[] constructors = myClass.getConstructors(); for (PsiMethod constructor : constructors) { final PsiStatement[] statements = constructor.getBody().getStatements(); if (statements.length > 0 && JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) { final PsiMethodCallExpression superConstructorCall = (PsiMethodCallExpression)((PsiExpressionStatement)statements[0]).getExpression(); PsiElement superConstructor = superConstructorCall.getMethodExpression().resolve(); if (superConstructor instanceof PsiMethod && ((PsiMethod)superConstructor).isConstructor()) { result.add(new InnerClassConstructor((PsiMethod)superConstructor)); } } } } // find overriding/implementing method { class InnerClassOverridingMethod extends InnerClassMethod { InnerClassOverridingMethod(PsiMethod method) { super(method); } @Override public void createMethod(PsiClass innerClass) throws IncorrectOperationException { OverriddenMethodClassMemberReferencesVisitor visitor = new OverriddenMethodClassMemberReferencesVisitor(); myClass.accept(visitor); final List<PsiAction> actions = visitor.getPsiActions(); for (PsiAction action : actions) { action.run(); } innerClass.add(myMethod); myMethod.delete(); // myMethod.replace(delegateMethod(myMethod)); } } for (PsiMethod method : myOverriddenMethods) { result.add(new InnerClassOverridingMethod(method)); } } // fix abstract methods { class InnerClassAbstractMethod extends InnerClassMethod { private final boolean myImplicitImplementation; InnerClassAbstractMethod(PsiMethod method, final boolean implicitImplementation) { super(method); myImplicitImplementation = implicitImplementation; } @Override public void createMethod(PsiClass innerClass) throws IncorrectOperationException { PsiSubstitutor substitutor = getSuperSubstitutor(myMethod.getContainingClass()); PsiMethod method = delegateMethod(myClass.getName() + ".this", myMethod, substitutor); final PsiClass containingClass = myMethod.getContainingClass(); if (myBaseClass.isInterface() || containingClass.isInterface()) { PsiUtil.setModifierProperty(method, PsiModifier.PUBLIC, true); } innerClass.add(method); if (!myImplicitImplementation) { final MethodSignature signature = myMethod.getSignature(substitutor); PsiMethod outerMethod = MethodSignatureUtil.findMethodBySignature(myClass, signature, false); if (outerMethod == null) { String visibility = checkOuterClassAbstractMethod(signature); PsiMethod newOuterMethod = (PsiMethod)myClass.add(myMethod); PsiUtil.setModifierProperty(newOuterMethod, visibility, true); if (containingClass.isInterface() && !innerClass.isInterface() && myMethod.getBody() == null) { PsiUtil.setModifierProperty(newOuterMethod, PsiModifier.ABSTRACT, true); } final PsiDocComment docComment = newOuterMethod.getDocComment(); if (docComment != null) { docComment.delete(); } } } } } PsiMethod[] methods = myBaseClass.getAllMethods(); for (PsiMethod method : methods) { if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { final MethodSignature signature = method.getSignature(getSuperSubstitutor(method.getContainingClass())); PsiMethod classMethod = MethodSignatureUtil.findMethodBySignature(myClass, signature, true); if (classMethod == null || classMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { result.add(new InnerClassAbstractMethod(method, false)); } else if ((myBaseClass.isInterface() && classMethod.getContainingClass() != myClass)) { // IDEADEV-19675 result.add(new InnerClassAbstractMethod(method, true)); } } } } return result; }