unrelated defaults: correct type if super classes come from different jdks (both 1.8 but of different versions)

This commit is contained in:
Anna Kozlova
2016-06-24 15:33:37 +03:00
parent 951cdba765
commit 3ee8b6d1e8
7 changed files with 67 additions and 33 deletions
@@ -15,11 +15,15 @@
*/
package com.intellij.psi.util;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashSet;
import java.util.List;
@@ -111,6 +115,7 @@ public class PsiSuperMethodUtil {
public static Map<MethodSignature, Set<PsiMethod>> collectOverrideEquivalents(@NotNull PsiClass aClass) {
final Map<MethodSignature, Set<PsiMethod>> overrideEquivalent =
new THashMap<MethodSignature, Set<PsiMethod>>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);
final GlobalSearchScope resolveScope = aClass.getResolveScope();
PsiClass[] supers = aClass.getSupers();
for (int i = 0; i < supers.length; i++) {
PsiClass superClass = supers[i];
@@ -122,10 +127,12 @@ public class PsiSuperMethodUtil {
if (subType) continue;
final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
for (HierarchicalMethodSignature hms : superClass.getVisibleSignatures()) {
final PsiMethod method = hms.getMethod();
PsiMethod method = hms.getMethod();
if (MethodSignatureUtil.findMethodBySignature(aClass, method.getSignature(superClassSubstitutor), false) != null) continue;
final PsiClass containingClass = method.getContainingClass();
final PsiClass containingClass = mapClass(method.getContainingClass(), resolveScope);
if (containingClass == null) continue;
method = containingClass.findMethodBySignature(method, false);
if (method == null) continue;
final PsiSubstitutor containingClassSubstitutor = TypeConversionUtil.getClassSubstitutor(containingClass, aClass, PsiSubstitutor.EMPTY);
if (containingClassSubstitutor == null) continue;
final PsiSubstitutor finalSubstitutor =
@@ -141,4 +148,30 @@ public class PsiSuperMethodUtil {
}
return overrideEquivalent;
}
@Nullable
public static PsiClass mapClass(PsiClass psiClass, final GlobalSearchScope resolveScope) {
if (psiClass == null) return null;
String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName == null) {
return psiClass;
}
PsiFile file = psiClass.getContainingFile();
if (file == null || !file.getViewProvider().isPhysical()) {
return psiClass;
}
final VirtualFile vFile = file.getVirtualFile();
if (vFile == null) {
return psiClass;
}
final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject());
if (!index.isInSource(vFile) && !index.isInLibrarySource(vFile) && !index.isInLibraryClasses(vFile)) {
return psiClass;
}
return JavaPsiFacade.getInstance(psiClass.getProject()).findClass(qualifiedName, resolveScope);
}
}
@@ -15,11 +15,10 @@
*/
package com.intellij.psi.impl;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiSuperMethodUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -56,7 +55,7 @@ class TypeCorrector extends PsiTypeMapper {
final PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics();
final PsiClass psiClass = classResolveResult.getElement();
if (psiClass != null && classResolveResult.getSubstitutor() == PsiSubstitutor.EMPTY) {
final PsiClass mappedClass = mapClass(psiClass);
final PsiClass mappedClass = PsiSuperMethodUtil.mapClass(psiClass, myResolveScope);
if (mappedClass == null || mappedClass == psiClass) return (T) classType;
}
}
@@ -79,7 +78,7 @@ class TypeCorrector extends PsiTypeMapper {
PsiUtilCore.ensureValid(psiClass);
final PsiClass mappedClass = mapClass(psiClass);
final PsiClass mappedClass = PsiSuperMethodUtil.mapClass(psiClass, myResolveScope);
if (mappedClass == null) return classType;
PsiClassType mappedType = new PsiCorrectedClassType(classType.getLanguageLevel(),
@@ -89,31 +88,6 @@ class TypeCorrector extends PsiTypeMapper {
return mappedType;
}
@Nullable
private PsiClass mapClass(@NotNull PsiClass psiClass) {
String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName == null) {
return psiClass;
}
PsiFile file = psiClass.getContainingFile();
if (file == null || !file.getViewProvider().isPhysical()) {
return psiClass;
}
final VirtualFile vFile = file.getVirtualFile();
if (vFile == null) {
return psiClass;
}
final FileIndexFacade index = FileIndexFacade.getInstance(file.getProject());
if (!index.isInSource(vFile) && !index.isInLibrarySource(vFile) && !index.isInLibraryClasses(vFile)) {
return psiClass;
}
return JavaPsiFacade.getInstance(psiClass.getProject()).findClass(qualifiedName, myResolveScope);
}
@NotNull
private PsiSubstitutor mapSubstitutor(PsiClass originalClass, PsiClass mappedClass, PsiSubstitutor substitutor) {
PsiTypeParameter[] typeParameters = mappedClass.getTypeParameters();
@@ -0,0 +1,4 @@
package p;
interface I {
default void foo();
}
@@ -0,0 +1,3 @@
package p;
public abstract class A implements I {}
@@ -0,0 +1,4 @@
package p;
interface I {
default void foo();
}
@@ -0,0 +1,8 @@
package p;
class EmptyValueIterator extends A implements ValueIterator {
}
interface ValueIterator extends I {}
@@ -18,7 +18,6 @@ package com.intellij.codeInsight;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.pom.java.LanguageLevel;
@@ -26,7 +25,6 @@ import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.*;
import com.intellij.util.Consumer;
public class MultipleJdksHighlightingTest extends UsefulTestCase {
@@ -197,6 +195,16 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
myFixture.checkHighlighting();
}
public void testUnrelatedDefaultsFromDifferentJdkVersions() throws Exception {
ModuleRootModificationUtil.addDependency(myJava8Module, myJava7Module);
myFixture.copyFileToProject("java7/p/I.java");
myFixture.copyFileToProject("java8/p/I.java");
final String testName = getTestName(false);
myFixture.configureByFiles("java8/p/" + testName + ".java", "java7/p/" + testName + ".java");
myFixture.checkHighlighting();
}
private void doTestWithoutLibrary() {
final String name = getTestName(false);
myFixture.configureByFiles("java7/p/" + name + ".java", "java8/p/" + name + ".java");