new inference: most specific with same functional interface presence

(cherry picked from commit f05ae78f4cfd030258264d717d7522ab0930d9a5)
This commit is contained in:
Anna Kozlova
2014-03-11 16:01:13 +01:00
parent 465325a6a6
commit 7d747c8cef
3 changed files with 52 additions and 8 deletions

View File

@@ -579,12 +579,19 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && myArgumentsList instanceof PsiExpressionList && (typeParameters1.length == 0 || typeParameters2.length == 0)) {
boolean toCompareFunctional = false;
for (int i = 0; i < getActualParametersLength(); i++) {
if (types1.length > 0 && LambdaUtil.isFunctionalType(types1[Math.min(i, types1.length - 1)]) &&
types2.length > 0 && LambdaUtil.isFunctionalType(types2[Math.min(i, types2.length - 1)])) {
types1AtSite[Math.min(i, types1.length - 1)] = PsiType.NULL;
types2AtSite[Math.min(i, types2.length - 1)] = PsiType.NULL;
toCompareFunctional = true;
if (types1.length > 0 && types2.length > 0) {
for (int i = 0; i < getActualParametersLength(); i++) {
final PsiType type1 = types1[Math.min(i, types1.length - 1)];
final PsiType type2 = types2[Math.min(i, types2.length - 1)];
//from 15.12.2.5 Choosing the Most Specific Method
//In addition, a functional interface type S is more specific than a functional interface type T for an expression exp
// if T is not a subtype of S and one of the following conditions apply.
if (LambdaUtil.isFunctionalType(type1) && !type1.isAssignableFrom(type2) &&
LambdaUtil.isFunctionalType(type2) && !type2.isAssignableFrom(type1)) {
types1AtSite[Math.min(i, types1.length - 1)] = PsiType.NULL;
types2AtSite[Math.min(i, types2.length - 1)] = PsiType.NULL;
toCompareFunctional = true;
}
}
}
@@ -597,8 +604,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
if (applicable12ignoreFunctionalType || applicable21ignoreFunctionalType) {
Specifics specifics = null;
for (int i = 0; i < getActualParametersLength(); i++) {
if (types1.length > 0 && types1AtSite[Math.min(i, types1.length - 1)] == PsiType.NULL &&
types2.length > 0 && types2AtSite[Math.min(i, types2.length - 1)] == PsiType.NULL) {
if (types1AtSite[Math.min(i, types1.length - 1)] == PsiType.NULL &&
types2AtSite[Math.min(i, types2.length - 1)] == PsiType.NULL) {
Specifics specific = isFunctionalTypeMoreSpecific(info1, info2, ((PsiExpressionList)myArgumentsList).getExpressions()[i], i);
if (specific == Specifics.NEITHER) {
specifics = Specifics.NEITHER;

View File

@@ -0,0 +1,33 @@
abstract class HighlightTestInfo {
protected final String[] filePaths;
public HighlightTestInfo(Disposable <warning descr="Parameter 'buf' is never used">buf</warning>, String... filePaths) {
this.filePaths = filePaths;
}
protected abstract HighlightTestInfo doTest();
}
class StreamMain {
private Disposable <warning descr="Private field 'testRootDisposable' is never assigned">testRootDisposable</warning>;
public HighlightTestInfo testFile(String... filePath) {
return new HighlightTestInfo(getTestRootDisposable(), filePath) {
public HighlightTestInfo doTest() {
return this;
}
};
}
public Disposable getTestRootDisposable() {
return testRootDisposable;
}
}
interface Disposable {
void dispose();
interface Parent extends Disposable {
void beforeTreeDispose();
}
}

View File

@@ -51,6 +51,10 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testMostSpecificForSameFunctionalTypes() throws Exception {
doTest();
}
private void doTest() {
doTest(true);
}