mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
complex inference algorithm for diamond
This commit is contained in:
+15
-3
@@ -107,6 +107,19 @@ public class GenericsHighlightUtil {
|
||||
}
|
||||
}
|
||||
|
||||
PsiDiamondType.DiamondInferenceResult inferenceResult = null;
|
||||
PsiTypeElement[] referenceElements = null;
|
||||
if (referenceParameterList != null) {
|
||||
referenceElements = referenceParameterList.getTypeParameterElements();
|
||||
if (referenceElements.length == 1 && referenceElements[0].getType() instanceof PsiDiamondType) {
|
||||
inferenceResult = ((PsiDiamondType)referenceElements[0].getType()).resolveInferredTypes();
|
||||
final String errorMessage = inferenceResult.getErrorMessage();
|
||||
if (errorMessage != null) {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, referenceElements[0], errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final PsiTypeParameter[] typeParameters = typeParameterListOwner.getTypeParameters();
|
||||
final int targetParametersNum = typeParameters.length;
|
||||
final int refParametersNum = referenceParameterList == null ? 0 : referenceParameterList.getTypeArguments().length;
|
||||
@@ -140,9 +153,8 @@ public class GenericsHighlightUtil {
|
||||
|
||||
// bounds check
|
||||
if (targetParametersNum > 0 && refParametersNum != 0) {
|
||||
final PsiTypeElement[] referenceElements = referenceParameterList.getTypeParameterElements();
|
||||
if (referenceElements.length == 1 && referenceElements[0].getType() instanceof PsiDiamondType) {
|
||||
final PsiType[] types = ((PsiDiamondType)referenceElements[0].getType()).getInferredTypes();
|
||||
if (inferenceResult != null) {
|
||||
final PsiType[] types = inferenceResult.getTypes();
|
||||
for (int i = 0; i < typeParameters.length; i++) {
|
||||
final PsiType type = types[i];
|
||||
final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, type, referenceElements[0]);
|
||||
|
||||
+28
-3
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -65,15 +66,39 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionT
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
if (PsiUtil.getLanguageLevel(expression).isAtLeast(LanguageLevel.JDK_1_7)) {
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
|
||||
final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final PsiReferenceParameterList parameterList = classReference.getParameterList();
|
||||
if (parameterList != null) {
|
||||
final PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
|
||||
if (typeElements.length > 0) {
|
||||
if (typeElements.length == 1 && typeElements[0].getType() instanceof PsiDiamondType) return;
|
||||
holder.registerProblem(parameterList, "Redundant type argument #ref #loc",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithDiamondFix());
|
||||
final PsiDiamondType.DiamondInferenceResult inferenceResult = PsiDiamondType.resolveInferredTypes(expression);
|
||||
if (inferenceResult.getErrorMessage() == null) {
|
||||
final PsiType[] types = inferenceResult.getTypes();
|
||||
final PsiType[] typeArguments = parameterList.getTypeArguments();
|
||||
if (types.length == typeArguments.length) {
|
||||
for (int i = 0, typeArgumentsLength = typeArguments.length; i < typeArgumentsLength; i++) {
|
||||
PsiType typeArgument = typeArguments[i];
|
||||
if (types[i] instanceof PsiWildcardType) {
|
||||
final PsiWildcardType wildcardType = (PsiWildcardType)types[i];
|
||||
final PsiType bound = wildcardType.getBound();
|
||||
if (bound != null) {
|
||||
if (wildcardType.isExtends()) {
|
||||
if (bound.isAssignableFrom(typeArgument)) continue;
|
||||
} else {
|
||||
if (typeArgument.isAssignableFrom(bound)) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!typeArgument.equals(types[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.registerProblem(parameterList, "Redundant type argument #ref #loc",
|
||||
ProblemHighlightType.LIKE_UNUSED_SYMBOL, new ReplaceWithDiamondFix());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ public class PsiImplUtil {
|
||||
types[i] = typeElements[i].getType();
|
||||
}
|
||||
if (types.length == 1 && types[0] instanceof PsiDiamondType) {
|
||||
return ((PsiDiamondType)types[0]).getInferredTypes();
|
||||
return ((PsiDiamondType)types[0]).resolveInferredTypes().getTypes();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
@@ -403,8 +403,8 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
final boolean forCompletion) {
|
||||
PsiTypeParameterListOwner owner = typeParameter.getOwner();
|
||||
Pair<PsiType, ConstraintType> substitution = null;
|
||||
if (owner instanceof PsiMethod && parent instanceof PsiMethodCallExpression) {
|
||||
PsiMethodCallExpression methodCall = (PsiMethodCallExpression)parent;
|
||||
if (owner instanceof PsiMethod && parent instanceof PsiCallExpression) {
|
||||
PsiCallExpression methodCall = (PsiCallExpression)parent;
|
||||
substitution = inferMethodTypeParameterFromParent(methodCall.getParent(), methodCall, typeParameter, substitutor, forCompletion);
|
||||
}
|
||||
return substitution;
|
||||
@@ -604,7 +604,7 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
}
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferMethodTypeParameterFromParent(PsiElement parent,
|
||||
PsiMethodCallExpression methodCall,
|
||||
PsiCallExpression methodCall,
|
||||
final PsiTypeParameter typeParameter,
|
||||
PsiSubstitutor substitutor,
|
||||
final boolean forCompletion) {
|
||||
@@ -701,13 +701,13 @@ public class PsiResolveHelperImpl implements PsiResolveHelper {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final ThreadLocal<List<PsiMethodCallExpression>> myBlockedForInferenceMethodCalls = new ThreadLocal<List<PsiMethodCallExpression>>() {
|
||||
protected List<PsiMethodCallExpression> initialValue() {
|
||||
return new ArrayList<PsiMethodCallExpression>(2);
|
||||
private static final ThreadLocal<List<PsiCallExpression>> myBlockedForInferenceMethodCalls = new ThreadLocal<List<PsiCallExpression>>() {
|
||||
protected List<PsiCallExpression> initialValue() {
|
||||
return new ArrayList<PsiCallExpression>(2);
|
||||
}
|
||||
};
|
||||
|
||||
private static Pair<PsiType, ConstraintType> inferTypeForCompletionFromCallContext(final PsiMethodCallExpression innerMethodCall,
|
||||
private static Pair<PsiType, ConstraintType> inferTypeForCompletionFromCallContext(final PsiCallExpression innerMethodCall,
|
||||
final PsiExpressionList expressionList,
|
||||
final PsiCallExpression contextCall,
|
||||
final PsiTypeParameter typeParameter) {
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class P<PT> {
|
||||
|
||||
class Test1 {
|
||||
void bar() {
|
||||
foo(new FF<>());
|
||||
foo<error descr="'foo(F<F<java.lang.String>>)' in 'Test1' cannot be applied to '(FF<java.lang.Object>)'">(new FF<>())</error>;
|
||||
}
|
||||
|
||||
void foo(F<F<String>> p) {}
|
||||
|
||||
+8
-8
@@ -8,29 +8,29 @@ class Neg01<X extends Number> {
|
||||
|
||||
void test() {
|
||||
Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("" ); //new Foo<Integer> created
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Neg01<?> n3 = new Neg01<><error descr="'Neg01(java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Neg01<?> n3 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
Neg01<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
|
||||
Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Integer> created
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error> {
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Integer> created
|
||||
Neg01<?> n7 = new Neg01<><error descr="'Neg01(java.lang.Number)' in 'Neg01' cannot be applied to '(java.lang.String)'">("")</error> {
|
||||
Neg01<?> n7 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Object> created
|
||||
Neg01<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n8 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Object> created
|
||||
|
||||
Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n9 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n10 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Neg01<?> n11 = new Neg01<><error descr="'Neg01(java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n10 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Neg01<?> n11 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
<error descr="Cannot resolve symbol 'Foo'">Foo</error><? super String> n12 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
|
||||
Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n13 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Integer> created
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n14 = new Neg01<><error descr="'Neg01(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
|
||||
Neg01<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n14 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Integer> created
|
||||
Neg01<?> n15 = new Neg01<><error descr="'Neg01(java.lang.Number, java.lang.String)' in 'Neg01' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
|
||||
Neg01<?> n15 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Object> created
|
||||
Neg01<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n16 = new Neg01<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Object> created
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Neg10 {
|
||||
static class Foo<X> {
|
||||
Foo(X x) {}
|
||||
}
|
||||
|
||||
<error descr="Incompatible types. Found: 'Neg10.Foo<java.lang.Integer>', required: 'Neg10.Foo<java.lang.Number>'">Foo<Number> fw = new Foo<>(1);</error>
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class Neg11 {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> { }
|
||||
Foo<?> f1 = new <error descr="Cannot resolve symbol 'UndeclaredName'">UndeclaredName</error><>(); //this is deliberate: aim is to test erroneous path
|
||||
Foo<?> f2 = new <error descr="Cannot resolve symbol 'UndeclaredName'">UndeclaredName</error><>() {}; //this is deliberate: aim is to test erroneous path
|
||||
}
|
||||
}
|
||||
+16
-16
@@ -10,29 +10,29 @@ class Neg02 {
|
||||
|
||||
void testSimple() {
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<?> f3 = new Foo<><error descr="'Foo(java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<?> f3 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error> {
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<?> f7 = new Foo< ><error descr="'Foo(java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error> {
|
||||
Foo<?> f7 = new Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<?> f11 = new Foo< ><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<?> f11 = new Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<?> f15 = new Foo< ><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
|
||||
Foo<?> f15 = new Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Object> created
|
||||
@@ -40,29 +40,29 @@ class Neg02 {
|
||||
|
||||
void testQualified() {
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<?> f3 = new Neg02.Foo< ><error descr="'Foo(java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<?> f3 = new Neg02.Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error> {
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<?> f7 = new Neg02.Foo< ><error descr="'Foo(java.lang.Number)' in 'Neg02.Foo' cannot be applied to '(java.lang.String)'">("")</error> {
|
||||
Foo<?> f7 = new Neg02.Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {
|
||||
}; //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<?> f11 = new Neg02.Foo< ><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<?> f11 = new Neg02.Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Neg02.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Integer> created
|
||||
Foo<?> f15 = new Neg02.Foo< ><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg02.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error> {
|
||||
Foo<?> f15 = new Neg02.Foo< <error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Neg02.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", "") {
|
||||
}; //new Foo<Object> created
|
||||
|
||||
+24
-24
@@ -7,67 +7,67 @@ class Neg03<U> {
|
||||
|
||||
void testSimple() {
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<?> f3 = new Foo<><error descr="'Foo(java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<?> f3 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> f7 = new Foo<><error descr="'Foo(java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<?> f7 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<?> f11 = new Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<?> f11 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> f15 = new Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<?> f15 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
|
||||
}
|
||||
|
||||
void testQualified_1() {
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<?> f3 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<?> f3 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> f7 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<?> f7 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<?> f11 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<?> f11 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> f15 = new Neg03<U>.Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<?> f15 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = new Neg03<U>.Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
|
||||
}
|
||||
|
||||
void testQualified_2(Neg03<U> n) {
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f1 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<?> f3 = n.new Foo<><error descr="'Foo(java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f2 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<?> f3 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f4 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f5 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> f7 = n.new Foo<><error descr="'Foo(java.lang.Number)' in 'Neg03.Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f6 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<?> f7 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f8 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f9 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<?> f11 = n.new Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f10 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<?> f11 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f12 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> f13 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = n.new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> f15 = n.new Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Neg03.Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> f14 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<?> f15 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> f16 = n.new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -6,23 +6,23 @@ class Neg04 {
|
||||
<Z> Foo(V x, Z z) {}
|
||||
}
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Integer> created
|
||||
Foo<?> n3 = new Foo<><error descr="'Foo(java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Integer> created
|
||||
Foo<?> n3 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n4 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n5 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> n7 = new Foo<><error descr="'Foo(java.lang.Number)' in 'Foo' cannot be applied to '(java.lang.String)'">("")</error>{}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n6 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Integer> created
|
||||
Foo<?> n7 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n8 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>(""){}; //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n9 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n10 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Integer> created
|
||||
Foo<?> n11 = new Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n10 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Integer> created
|
||||
Foo<?> n11 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n12 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""); //new Foo<Object> created
|
||||
|
||||
Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'">String</error>> n13 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n14 = new Foo<><error descr="'Foo(java.lang.String & java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Integer> created
|
||||
Foo<?> n15 = new Foo<><error descr="'Foo(java.lang.Number, java.lang.String)' in 'Foo' cannot be applied to '(java.lang.String, java.lang.String)'">("", "")</error>{}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? extends String' is not within its bound; should extend 'java.lang.Number'">? extends String</error>> n14 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Integer> created
|
||||
Foo<?> n15 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
|
||||
Foo<<error descr="Type parameter '? super String' is not within its bound; should extend 'java.lang.Number'">? super String</error>> n16 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("", ""){}; //new Foo<Object> created
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Neg06 {
|
||||
interface ISuperFoo<X> {}
|
||||
interface IFoo<X extends Number> extends ISuperFoo<X> {}
|
||||
|
||||
static class CSuperFoo<X> {}
|
||||
static class CFoo<X extends Number> extends CSuperFoo<X> {}
|
||||
|
||||
ISuperFoo<String> isf = new IFoo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>() {};
|
||||
CSuperFoo<String> csf1 = new CFoo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>();
|
||||
CSuperFoo<String> csf2 = new CFoo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>() {};
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class Neg07 {
|
||||
static class SuperFoo<X> {}
|
||||
static class Foo<X extends Number> extends SuperFoo<X> {
|
||||
Foo(X x) {}
|
||||
}
|
||||
|
||||
SuperFoo<String> sf1 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("");
|
||||
SuperFoo<String> sf2 = new Foo<<error descr="Type parameter 'java.lang.String' is not within its bound; should extend 'java.lang.Number'"></error>>("") {};
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
class Neg08 {
|
||||
static class Foo<X> {
|
||||
Foo(X x) { }
|
||||
}
|
||||
|
||||
static class DoubleFoo<X,Y> {
|
||||
DoubleFoo(X x,Y y) { }
|
||||
}
|
||||
|
||||
static class TripleFoo<X,Y,Z> {
|
||||
TripleFoo(X x,Y y,Z z) { }
|
||||
}
|
||||
|
||||
Foo<? extends Integer> fi = new Foo<>(1);
|
||||
Foo<?> fw = new Foo<<error descr="Cannot infer type arguments for Foo<> because type Foo<? extends Integer> inferred is not allowed in current context"></error>>(fi);
|
||||
Foo<? extends Double> fd = new Foo<>(3.0);
|
||||
DoubleFoo<?,?> dw = new DoubleFoo<<error descr="Cannot infer type arguments for DoubleFoo<> because type Foo<? extends Integer> inferred is not allowed in current context"></error>>(fi,fd);
|
||||
Foo<String> fs = new Foo<>("one");
|
||||
TripleFoo<?,?,?> tw = new TripleFoo<<error descr="Cannot infer type arguments for TripleFoo<> because type Foo<? extends Integer> inferred is not allowed in current context"></error>>(fi,fd,fs);
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class Neg09 {
|
||||
static class Foo<X extends Number & Comparable<Number>> {}
|
||||
static class DoubleFoo<X extends Number & Comparable<Number>,
|
||||
Y extends Number & Comparable<Number>> {}
|
||||
static class TripleFoo<X extends Number & Comparable<Number>,
|
||||
Y extends Number & Comparable<Number>,
|
||||
Z> {}
|
||||
|
||||
Foo<?> fw = new Foo<<error descr="Cannot infer type arguments for Foo<> because type ? extends Number inferred is not allowed in current context"></error>>();
|
||||
DoubleFoo<?,?> dw = new DoubleFoo<<error descr="Cannot infer type arguments for DoubleFoo<> because type ? extends Number inferred is not allowed in current context"></error>>();
|
||||
TripleFoo<?,?,?> tw = new TripleFoo<<error descr="Cannot infer type arguments for TripleFoo<> because type ? extends Number inferred is not allowed in current context"></error>>();
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public class Pos05 {
|
||||
|
||||
static class Foo<X> {
|
||||
Foo(X x) {}
|
||||
}
|
||||
|
||||
void m(Foo<Integer> fi) {}
|
||||
|
||||
void test() {
|
||||
m(new Foo<>(1));
|
||||
}
|
||||
}
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
// "Replace with <>" "true"
|
||||
public class Test {
|
||||
F<F<String>> f = new FF<>();
|
||||
}
|
||||
|
||||
class FF<X> extends F<X>{}
|
||||
class F<T> {}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
// "Replace with <>" "true"
|
||||
public class Test {
|
||||
void bar() {
|
||||
foo(new FF<>());
|
||||
}
|
||||
|
||||
void foo(F<F<String>> p) {}
|
||||
}
|
||||
|
||||
class FF<X> extends F<X>{}
|
||||
class F<T> {}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<>() {};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Replace with <>" "true"
|
||||
// "Replace with <>" "false"
|
||||
public class Test {
|
||||
F<F<String>> f = new FF<Str<caret>ing>();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// "Replace with <>" "true"
|
||||
// "Replace with <>" "false"
|
||||
public class Test {
|
||||
void bar() {
|
||||
foo(new FF<Str<caret>ing>());
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "false"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Nu<caret>mber>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Num<caret>ber>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Inte<caret>ger>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "false"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Nu<caret>mber>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Numb<caret>er>() {};
|
||||
Foo<?> f6 = new Foo<Integer>() {};
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Replace with <>" "true"
|
||||
class Test {
|
||||
|
||||
void test() {
|
||||
class Foo<X extends Number> {
|
||||
Foo() {}
|
||||
Foo(X x) {}
|
||||
}
|
||||
Foo<Number> f1 = new Foo<Number>(1);
|
||||
Foo<?> f2 = new Foo<Number>();
|
||||
Foo<?> f3 = new Foo<Integer>();
|
||||
Foo<Number> f4 = new Foo<Number>(1) {};
|
||||
Foo<?> f5 = new Foo<Number>() {};
|
||||
Foo<?> f6 = new Foo<In<caret>teger>() {};
|
||||
}
|
||||
}
|
||||
+30
@@ -58,6 +58,10 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondPos5() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg1() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
@@ -78,6 +82,32 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg6() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg7() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg8() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg9() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg10() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
public void testDiamondNeg11() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void testDiamondMisc() throws Exception {
|
||||
doTest(false, false);
|
||||
}
|
||||
|
||||
@@ -16,15 +16,19 @@
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: Jul 30, 2010
|
||||
@@ -82,152 +86,216 @@ public class PsiDiamondType extends PsiType {
|
||||
return new PsiType[]{getJavaLangObject(myManager, getResolveScope())};
|
||||
}
|
||||
|
||||
public PsiType[] getInferredTypes() {
|
||||
final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(myTypeElement, PsiDeclarationStatement.class);
|
||||
if (declarationStatement != null) {
|
||||
final PsiElement[] declaredElements = declarationStatement.getDeclaredElements();
|
||||
if (declaredElements.length > 0 && declaredElements[0] instanceof PsiVariable) {
|
||||
return getComponentTypes((PsiVariable)declaredElements[0]);
|
||||
}
|
||||
public DiamondInferenceResult resolveInferredTypes() {
|
||||
final PsiNewExpression newExpression = PsiTreeUtil.getParentOfType(myTypeElement, PsiNewExpression.class);
|
||||
if (newExpression == null) {
|
||||
return PsiDiamondType.DiamondInferenceResult.NULL_RESULT;
|
||||
}
|
||||
|
||||
final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(myTypeElement, PsiAssignmentExpression.class);
|
||||
if (assignmentExpression != null) {
|
||||
final PsiExpression lExpression = assignmentExpression.getLExpression();
|
||||
if (lExpression instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolved = ((PsiReferenceExpression)lExpression).resolve();
|
||||
if (resolved instanceof PsiVariable) {
|
||||
return getComponentTypes(((PsiVariable)resolved));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiExpression psiExpression = PsiTreeUtil.getParentOfType(myTypeElement, PsiExpression.class);
|
||||
while (psiExpression != null) {
|
||||
final PsiElement parent = psiExpression.getParent();
|
||||
if (parent instanceof PsiExpression) {
|
||||
psiExpression = (PsiExpression)parent;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (psiExpression != null) {
|
||||
final PsiElement parent = psiExpression.getParent();
|
||||
if (parent instanceof PsiExpressionList) {
|
||||
final PsiElement parentParent = parent.getParent();
|
||||
if (parentParent instanceof PsiCallExpression) {
|
||||
final JavaResolveResult resolveResult = ((PsiCallExpression)parentParent).resolveMethodGenerics();
|
||||
final PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
final PsiElement element = resolveResult.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
final int paramIdx = ArrayUtil.find(((PsiExpressionList)parent).getExpressions(), psiExpression);
|
||||
if (paramIdx > -1) {
|
||||
final PsiParameter parameter =
|
||||
((PsiMethod)element).getParameterList().getParameters()[paramIdx];
|
||||
return getComponentTypes(substitutor.substitute(parameter.getType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (parent instanceof PsiVariable) {
|
||||
return getComponentTypes((PsiVariable)parent);
|
||||
} else if (parent instanceof PsiReturnStatement) {
|
||||
final PsiMethod containingMethod = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
|
||||
if (containingMethod != null) {
|
||||
final PsiType returnType = containingMethod.getReturnType();
|
||||
if (returnType != null) {
|
||||
final PsiExpression returnValue = ((PsiReturnStatement)parent).getReturnValue();
|
||||
if (returnValue instanceof PsiNewExpression) {
|
||||
return getComponentTypes(returnType, returnValue);
|
||||
}
|
||||
return getComponentTypes(returnType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL_TYPES;
|
||||
return resolveInferredTypes(newExpression);
|
||||
}
|
||||
|
||||
private static PsiType[] getComponentTypes(PsiVariable declaredElement) {
|
||||
final PsiType lType = declaredElement.getType();
|
||||
final PsiExpression initializer = declaredElement.getInitializer();
|
||||
return getComponentTypes(lType, initializer);
|
||||
}
|
||||
|
||||
private static PsiType[] getComponentTypes(PsiType lType, PsiExpression initializer) {
|
||||
if (initializer instanceof PsiNewExpression) {
|
||||
final PsiNewExpression newExpression = (PsiNewExpression)initializer;
|
||||
final PsiJavaCodeReferenceElement classReference = newExpression.getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final String text = classReference.getReferenceName();
|
||||
if (text != null) {
|
||||
final PsiClass psiClass =
|
||||
JavaPsiFacade.getInstance(initializer.getProject()).getResolveHelper().resolveReferencedClass(text, initializer);
|
||||
final PsiType substitute = substitute(psiClass, lType);
|
||||
if (substitute != null) {
|
||||
lType = substitute;
|
||||
}
|
||||
public static DiamondInferenceResult resolveInferredTypes(PsiNewExpression newExpression) {
|
||||
final PsiClass psiClass = findClass(newExpression);
|
||||
if (psiClass == null) return DiamondInferenceResult.NULL_RESULT;
|
||||
final PsiMethod constructor = findConstructor(psiClass, newExpression);
|
||||
PsiTypeParameter[] params = getAllTypeParams(constructor, psiClass);
|
||||
PsiMethod staticFactory = generateStaticFactory(constructor, psiClass, params);
|
||||
if (staticFactory == null) {
|
||||
return DiamondInferenceResult.NULL_RESULT;
|
||||
}
|
||||
final PsiSubstitutor inferredSubstitutor = inferTypeParametersForStaticFactory(staticFactory, newExpression);
|
||||
final PsiTypeParameter[] parameters = staticFactory.getTypeParameters();
|
||||
final PsiTypeParameter[] classParameters = psiClass.getTypeParameters();
|
||||
final PsiJavaCodeReferenceElement classOrAnonymousClassReference = newExpression.getClassOrAnonymousClassReference();
|
||||
LOG.assertTrue(classOrAnonymousClassReference != null);
|
||||
final DiamondInferenceResult result = new DiamondInferenceResult(classOrAnonymousClassReference.getReferenceName() + "<>");
|
||||
for (PsiTypeParameter parameter : parameters) {
|
||||
for (PsiTypeParameter classParameter : classParameters) {
|
||||
if (Comparing.strEqual(classParameter.getName(), parameter.getName())) {
|
||||
result.addInferredType(inferredSubstitutor.substitute(parameter));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getComponentTypes(lType);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod findConstructor(PsiClass containingClass, PsiNewExpression newExpression) {
|
||||
final PsiExpressionList argumentList = newExpression.getArgumentList();
|
||||
if (argumentList == null) return null;
|
||||
final Project project = newExpression.getProject();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
final JavaResolveResult result =
|
||||
resolveHelper.resolveConstructor(facade.getElementFactory().createType(containingClass), argumentList, argumentList);
|
||||
return (PsiMethod)result.getElement();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType substitute(PsiClass inheritor, PsiType baseType) {
|
||||
if (inheritor == null) return null;
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(inheritor.getProject());
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(baseType);
|
||||
final PsiClass baseClass = resolveResult.getElement();
|
||||
if (baseClass == null) return null;
|
||||
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getClassSubstitutor(baseClass, inheritor, PsiSubstitutor.EMPTY);
|
||||
if (superSubstitutor == null) return null;
|
||||
|
||||
final PsiSubstitutor baseSubstitutor = resolveResult.getSubstitutor();
|
||||
|
||||
PsiSubstitutor inheritorSubstitutor = PsiSubstitutor.EMPTY;
|
||||
for (PsiTypeParameter inheritorParameter : PsiUtil.typeParametersIterable(inheritor)) {
|
||||
for (PsiTypeParameter baseParameter : PsiUtil.typeParametersIterable(baseClass)) {
|
||||
final PsiType substituted = superSubstitutor.substitute(baseParameter);
|
||||
PsiType arg = baseSubstitutor.substitute(baseParameter);
|
||||
if (arg instanceof PsiWildcardType) arg = ((PsiWildcardType)arg).getExtendsBound();
|
||||
PsiType substitution = resolveHelper.getSubstitutionForTypeParameter(inheritorParameter,
|
||||
substituted,
|
||||
arg,
|
||||
true,
|
||||
PsiUtil.getLanguageLevel(inheritor));
|
||||
if (PsiType.NULL.equals(substitution) || substitution instanceof PsiWildcardType) continue;
|
||||
if (substitution == null) {
|
||||
continue;
|
||||
}
|
||||
inheritorSubstitutor = inheritorSubstitutor.put(inheritorParameter, substitution);
|
||||
break;
|
||||
private static PsiClass findClass(PsiNewExpression newExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = newExpression.getClassOrAnonymousClassReference();
|
||||
if (classReference != null) {
|
||||
final String text = classReference.getReferenceName();
|
||||
if (text != null) {
|
||||
final Project project = newExpression.getProject();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
return resolveHelper.resolveReferencedClass(text, newExpression);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
PsiType toAdd = facade.getElementFactory().createType(inheritor, inheritorSubstitutor);
|
||||
if (baseType.isAssignableFrom(toAdd)) {
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiType[] getComponentTypes(PsiType type) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiType[] types = ((PsiClassType)type).getParameters();
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
PsiType currentType = types[i];
|
||||
if (currentType instanceof PsiWildcardType) {
|
||||
final PsiType bound = ((PsiWildcardType)currentType).getBound();
|
||||
if (bound != null) {
|
||||
types[i] = bound;
|
||||
}
|
||||
}
|
||||
@Nullable
|
||||
private static PsiMethod generateStaticFactory(@Nullable PsiMethod constructor, PsiClass containingClass, PsiTypeParameter[] params) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append("public static ");
|
||||
buf.append("<");
|
||||
buf.append(StringUtil.join(params, new Function<PsiTypeParameter, String>() {
|
||||
@Override
|
||||
public String fun(PsiTypeParameter psiTypeParameter) {
|
||||
return psiTypeParameter.getName();
|
||||
}
|
||||
return types;
|
||||
}, ", "));
|
||||
buf.append(">");
|
||||
|
||||
final String qualifiedName = containingClass.getQualifiedName();
|
||||
buf.append(qualifiedName != null ? qualifiedName : containingClass.getName());
|
||||
final PsiTypeParameter[] parameters = containingClass.getTypeParameters();
|
||||
buf.append("<");
|
||||
buf.append(StringUtil.join(parameters, new Function<PsiTypeParameter, String>() {
|
||||
@Override
|
||||
public String fun(PsiTypeParameter psiTypeParameter) {
|
||||
return psiTypeParameter.getName();
|
||||
}
|
||||
}, ", "));
|
||||
buf.append("> ");
|
||||
|
||||
String staticFactoryName = "staticFactory";
|
||||
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(containingClass.getProject());
|
||||
staticFactoryName = styleManager.suggestUniqueVariableName(staticFactoryName, containingClass, false);
|
||||
buf.append(staticFactoryName);
|
||||
if (constructor == null) {
|
||||
buf.append("()");
|
||||
}
|
||||
else {
|
||||
buf.append("(").append(StringUtil.join(constructor.getParameterList().getParameters(), new Function<PsiParameter, String>() {
|
||||
@Override
|
||||
public String fun(PsiParameter psiParameter) {
|
||||
return psiParameter.getType().getCanonicalText() + " " + psiParameter.getName();
|
||||
}
|
||||
}, ",")).append(")");
|
||||
}
|
||||
buf.append("{}");
|
||||
|
||||
return JavaPsiFacade.getElementFactory(containingClass.getProject()).createMethodFromText(buf.toString(), constructor != null ? constructor : containingClass);
|
||||
}
|
||||
|
||||
private static PsiTypeParameter[] getAllTypeParams(PsiTypeParameterListOwner listOwner, PsiClass containingClass) {
|
||||
Set<PsiTypeParameter> params = new LinkedHashSet<PsiTypeParameter>();
|
||||
if (listOwner != null) {
|
||||
Collections.addAll(params, listOwner.getTypeParameters());
|
||||
}
|
||||
Collections.addAll(params, containingClass.getTypeParameters());
|
||||
return params.toArray(new PsiTypeParameter[params.size()]);
|
||||
}
|
||||
|
||||
|
||||
private static PsiSubstitutor inferTypeParametersForStaticFactory(@NotNull PsiMethod staticFactoryMethod,
|
||||
PsiNewExpression expression) {
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(staticFactoryMethod.getProject());
|
||||
final PsiResolveHelper resolveHelper = facade.getResolveHelper();
|
||||
final PsiParameter[] parameters = staticFactoryMethod.getParameterList().getParameters();
|
||||
final PsiExpression[] expressions = expression.getArgumentList().getExpressions();
|
||||
return resolveHelper
|
||||
.inferTypeArguments(staticFactoryMethod.getTypeParameters(), parameters, expressions, PsiSubstitutor.EMPTY, expression, false);
|
||||
}
|
||||
|
||||
public static class DiamondInferenceResult {
|
||||
public static final DiamondInferenceResult NULL_RESULT = new DiamondInferenceResult() {
|
||||
@Override
|
||||
public PsiType[] getTypes() {
|
||||
return NULL_TYPES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return "Cannot infer arguments";
|
||||
}
|
||||
};
|
||||
|
||||
private List<PsiType> myInferredTypes = new ArrayList<PsiType>();
|
||||
private String myErrorMessage;
|
||||
|
||||
private String myNewExpressionPresentableText;
|
||||
|
||||
public DiamondInferenceResult() {
|
||||
}
|
||||
|
||||
public DiamondInferenceResult(String expressionPresentableText) {
|
||||
myNewExpressionPresentableText = expressionPresentableText;
|
||||
}
|
||||
|
||||
public PsiType[] getTypes() {
|
||||
if (myErrorMessage != null) {
|
||||
return NULL_TYPES;
|
||||
}
|
||||
return myInferredTypes.toArray(new PsiType[myInferredTypes.size()]);
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return myErrorMessage;
|
||||
}
|
||||
|
||||
public void addInferredType(PsiType psiType) {
|
||||
if (myErrorMessage != null) return;
|
||||
if (psiType == null) {
|
||||
myErrorMessage = "Cannot infer type arguments for " + myNewExpressionPresentableText;
|
||||
} else if (!isValid(psiType)) {
|
||||
myErrorMessage = "Cannot infer type arguments for " +
|
||||
myNewExpressionPresentableText + " because type " + psiType.getPresentableText() + " inferred is not allowed in current context";
|
||||
} else {
|
||||
myInferredTypes.add(psiType);
|
||||
}
|
||||
}
|
||||
|
||||
private static Boolean isValid(PsiType type) {
|
||||
return type.accept(new PsiTypeVisitor<Boolean>() {
|
||||
@Override
|
||||
public Boolean visitType(PsiType type) {
|
||||
return !(type instanceof PsiIntersectionType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitWildcardType(PsiWildcardType wildcardType) {
|
||||
final PsiType bound = wildcardType.getBound();
|
||||
if (bound != null) {
|
||||
if (bound instanceof PsiIntersectionType) return false;
|
||||
return bound.accept(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitClassType(PsiClassType classType) {
|
||||
for (PsiType psiType : classType.getParameters()) {
|
||||
if (!psiType.accept(this)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return NULL_TYPES;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user