allow to implement and override default methods in java 8 (IDEA-103180) [roma]

(cherry picked from commit 6fc2a889a092365431b92d7f03b8d2057a82d8be)
This commit is contained in:
anna
2013-03-15 22:04:47 +01:00
parent 1b9cb2dce0
commit 5b83d0d343
4 changed files with 65 additions and 4 deletions
@@ -4,6 +4,7 @@ import com.intellij.codeInsight.MemberImplementorExplorer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.infos.CandidateInfo;
import com.intellij.psi.util.MethodSignature;
@@ -63,9 +64,9 @@ public class OverrideImplementExploreUtil {
}
Map<MethodSignature, PsiMethod> map = hisClass.isInterface() || method.hasModifierProperty(PsiModifier.ABSTRACT) ? abstracts : concretes;
PsiMethod other = map.get(signature);
if (other == null || preferLeftForImplement(method, other)) {
map.put(signature, method);
fillMap(signature, method, map);
if (isDefaultMethod(aClass, method)) {
fillMap(signature, method, concretes);
}
}
@@ -92,6 +93,18 @@ public class OverrideImplementExploreUtil {
return result;
}
private static boolean isDefaultMethod(PsiClass aClass, PsiMethod method) {
return method.hasModifierProperty(PsiModifier.DEFAULT) &&
PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8);
}
private static void fillMap(HierarchicalMethodSignature signature, PsiMethod method, Map<MethodSignature, PsiMethod> map) {
final PsiMethod other = map.get(signature);
if (other == null || preferLeftForImplement(method, other)) {
map.put(signature, method);
}
}
public static void collectMethodsToImplement(PsiClass aClass,
Map<MethodSignature, PsiMethod> abstracts,
Map<MethodSignature, PsiMethod> finals,
@@ -103,7 +116,8 @@ public class OverrideImplementExploreUtil {
PsiMethod concrete = concretes.get(signature);
if (concrete == null
|| PsiUtil.getAccessLevel(concrete.getModifierList()) < PsiUtil.getAccessLevel(abstractOne.getModifierList())
|| !abstractOne.getContainingClass().isInterface() && abstractOne.getContainingClass().isInheritor(concrete.getContainingClass(), true)) {
|| !abstractOne.getContainingClass().isInterface() && abstractOne.getContainingClass().isInheritor(concrete.getContainingClass(), true)
|| isDefaultMethod(aClass, abstractOne)) {
if (finals.get(signature) == null) {
PsiSubstitutor subst = correctSubstitutor(abstractOne, signature.getSubstitutor());
CandidateInfo info = new CandidateInfo(abstractOne, subst);
@@ -0,0 +1,39 @@
interface A<T> {
default void m(T t) { }
}
class MyClass<T> implements A<T> {
@Override
public void m(T t) {
<selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
}
public MyClass() {
super(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public int hashCode() {
return super.hashCode(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public boolean equals(Object obj) {
return super.equals(obj); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
public String toString() {
return super.toString(); //To change body of overridden methods use File | Settings | File Templates.
}
@Override
protected void finalize() throws Throwable {
super.finalize(); //To change body of overridden methods use File | Settings | File Templates.
}
}
@@ -0,0 +1,7 @@
interface A<T> {
default void m(T t) { }
}
class MyClass<T> implements A<T> {
<caret>
}
@@ -66,6 +66,7 @@ public class OverrideImplementTest extends LightCodeInsightTestCase {
public void testResolveTypeParamConflict() { doTest(false); }
public void testImplementExtensionMethods() { doTest8(false, true); }
public void testOverrideExtensionMethods() { doTest8(false, false); }
public void testDoNotImplementExtensionMethods() { doTest8(false, true); }
public void testLongFinalParameterList() {