mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
invocation type inference: don't create fresh variables for all type parameters but only for those where wildcards are used in return type (IDEA-155627; IDEA-151220; IDEA-151387)
This commit is contained in:
+23
-3
@@ -19,6 +19,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.*;
|
||||
@@ -700,15 +701,15 @@ public class InferenceSession {
|
||||
LOG.assertTrue(returnType instanceof PsiClassType);
|
||||
PsiClassType substitutedCapture = (PsiClassType)PsiUtil.captureToplevelWildcards(returnType, myContext);
|
||||
final PsiTypeParameter[] typeParameters = psiClass.getTypeParameters();
|
||||
final InferenceVariable[] copy = initBounds(null, typeParameters);
|
||||
|
||||
final PsiType[] parameters = substitutedCapture.getParameters();
|
||||
final InferenceVariable[] copy = initFreshVariablesForCapturedBounds(typeParameters, parameters);
|
||||
final PsiType[] newParameters = new PsiType[parameters.length];
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myManager.getProject());
|
||||
int idx = 0;
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
newParameters[i] = parameters[i];
|
||||
if (parameters[i] instanceof PsiCapturedWildcardType) {
|
||||
newParameters[i] = elementFactory.createType(copy[i]);
|
||||
newParameters[i] = elementFactory.createType(copy[idx++]);
|
||||
}
|
||||
}
|
||||
substitutedCapture = elementFactory.createType(psiClass, newParameters);
|
||||
@@ -731,6 +732,25 @@ public class InferenceSession {
|
||||
}
|
||||
}
|
||||
|
||||
private InferenceVariable[] initFreshVariablesForCapturedBounds(PsiTypeParameter[] typeParameters, PsiType[] parameters) {
|
||||
if (Registry.is("javac.fresh.variables.for.captured.wildcards.only")) {
|
||||
final List<PsiTypeParameter> capturedParams = new ArrayList<PsiTypeParameter>();
|
||||
|
||||
PsiSubstitutor restParamSubstitution = PsiSubstitutor.EMPTY;
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiType parameter = parameters[i];
|
||||
if (parameter instanceof PsiCapturedWildcardType) {
|
||||
capturedParams.add(typeParameters[i]);
|
||||
}
|
||||
else {
|
||||
restParamSubstitution = restParamSubstitution.put(typeParameters[i], parameter);
|
||||
}
|
||||
}
|
||||
return initBounds(null, restParamSubstitution, capturedParams.toArray(new PsiTypeParameter[0]));
|
||||
}
|
||||
return initBounds(null, typeParameters);
|
||||
}
|
||||
|
||||
private InferenceVariable shouldResolveAndInstantiate(PsiType returnType, PsiType targetType) {
|
||||
final InferenceVariable inferenceVariable = getInferenceVariable(returnType);
|
||||
if (inferenceVariable != null) {
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
class Test {
|
||||
static class IterableSubject<S extends IterableSubject<S, C>, C> {}
|
||||
|
||||
public static <J> IterableSubject<? extends IterableSubject<?, J>, J> bar(Iterable<J> target) {
|
||||
return foo(target);
|
||||
}
|
||||
|
||||
public static <J> IterableSubject<? extends IterableSubject<?, J>, J> foo(Iterable<J> target) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class Test1 {
|
||||
private class XBreakpoint<P> {}
|
||||
private class XBreakpointType<T extends XBreakpoint<P>, P> {}
|
||||
|
||||
abstract <B extends XBreakpoint<?>> XBreakpointType<B, ?>
|
||||
findBreakpointType( Class<? extends XBreakpointType<B, ?>> typeClass);
|
||||
|
||||
<U extends XBreakpoint<?>> void createXBreakpoint(Class<? extends XBreakpointType<U, ?>> typeCls) {
|
||||
final XBreakpointType<U, ?> type = findBreakpointType(typeCls);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Test2 {
|
||||
static abstract class AbstractIterableAssert<S extends AbstractIterableAssert<S, A, T>, A extends Iterable<? extends T>, T> {}
|
||||
|
||||
public static <T1> AbstractIterableAssert<?, ? extends Iterable<? extends T1>, T1> bar(Iterable<? extends T1> actual) {
|
||||
return foo(actual);
|
||||
}
|
||||
|
||||
public static <T> AbstractIterableAssert<?, ? extends Iterable<? extends T>, T> foo(Iterable<? extends T> actual) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+4
@@ -468,6 +468,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase
|
||||
}
|
||||
}
|
||||
|
||||
public void testCreateFreshVariablesOnlyForWildcardPlacesDuringReturnTypeProcessing() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
@@ -623,6 +623,10 @@ linux.jdk.accessibility.atkwrapper.block=true
|
||||
javac.unchecked.subtyping.during.incorporation=true
|
||||
javac.unchecked.subtyping.during.incorporation.description=Javac performs unchecked subtyping during incorporation, accepting code which is rejected by the spec and by the eclipse compiler
|
||||
|
||||
javac.fresh.variables.for.captured.wildcards.only=true
|
||||
javac.fresh.variables.for.captured.wildcards.only.description=JLS 18.5.2: if R \u03B8 is a parameterized type, G<A1, ..., An>, and one of A1, ..., An is a wildcard, then, for fresh inference variables \u03B21, ..., \u03B2n ... \
|
||||
Javac creates fresh variables only for i: Ai is a wildcard
|
||||
|
||||
check.power.supply.for.mbp=false
|
||||
check.power.supply.for.mbp.description=Check for discrete video card and power supply on MBPs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user