diamonds: 1.7 type inference for New Expressions

This commit is contained in:
anna
2010-08-05 15:54:23 +04:00
parent d946490998
commit a9bb49eb29
26 changed files with 759 additions and 69 deletions
@@ -116,7 +116,7 @@ public class GenericsHighlightUtil {
final PsiTypeParameter[] typeParameters = typeParameterListOwner.getTypeParameters();
final int targetParametersNum = typeParameters.length;
final int refParametersNum = referenceParameterList == null ? 0 : referenceParameterList.getTypeParameterElements().length;
final int refParametersNum = referenceParameterList == null ? 0 : referenceParameterList.getTypeArguments().length;
if (targetParametersNum != refParametersNum && refParametersNum != 0) {
final String description;
if (targetParametersNum == 0) {
@@ -148,36 +148,18 @@ public class GenericsHighlightUtil {
// bounds check
if (targetParametersNum > 0 && refParametersNum != 0) {
final PsiTypeElement[] referenceElements = referenceParameterList.getTypeParameterElements();
for (int i = 0; i < typeParameters.length; i++) {
PsiTypeParameter classParameter = typeParameters[i];
final PsiTypeElement typeElement = referenceElements[i];
final PsiType type = typeElement.getType();
if (!(type instanceof PsiClassType)) continue;
final PsiClass referenceClass = ((PsiClassType)type).resolve();
if (referenceClass == null) continue;
final PsiClassType[] bounds = classParameter.getSuperTypes();
for (PsiClassType type1 : bounds) {
PsiType bound = substitutor.substitute(type1);
if (!TypeConversionUtil.isAssignable(bound, type, false)) {
PsiClass boundClass = bound instanceof PsiClassType ? ((PsiClassType)bound).resolve() : null;
@NonNls final String messageKey = boundClass == null || referenceClass.isInterface() == boundClass.isInterface()
? "generics.type.parameter.is.not.within.its.bound.extend"
: "generics.type.parameter.is.not.within.its.bound.implement";
String description = JavaErrorMessages.message(messageKey,
HighlightUtil.formatClass(referenceClass),
HighlightUtil.formatType(bound));
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
typeElement,
description);
if (bound instanceof PsiClassType) {
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createExtendsListFix(referenceClass, (PsiClassType)bound, true),
null);
}
return highlightInfo;
}
if (referenceElements.length == 1 && referenceElements[0].getType() instanceof PsiDiamondType) {
final PsiType[] types = ((PsiDiamondType)referenceElements[0].getType()).getInferredTypes();
for (int i = 0; i < typeParameters.length; i++) {
final PsiType type = types[i];
final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, type, referenceElements[0]);
if (highlightInfo != null) return highlightInfo;
}
} else {
for (int i = 0; i < typeParameters.length; i++) {
final PsiTypeElement typeElement = referenceElements[i];
final HighlightInfo highlightInfo = checkTypeParameterWithinItsBound(typeParameters[i], substitutor, typeElement.getType(), typeElement);
if (highlightInfo != null) return highlightInfo;
}
}
}
@@ -185,6 +167,42 @@ public class GenericsHighlightUtil {
return null;
}
@Nullable
private static HighlightInfo checkTypeParameterWithinItsBound(final PsiTypeParameter classParameter,
final PsiSubstitutor substitutor,
final PsiType type,
final PsiElement typeElement2Highlight) {
if (!(type instanceof PsiClassType)) return null;
final PsiClass referenceClass = ((PsiClassType)type).resolve();
if (referenceClass == null) return null;
final PsiClassType[] bounds = classParameter.getSuperTypes();
for (PsiClassType type1 : bounds) {
PsiType bound = substitutor.substitute(type1);
if (!TypeConversionUtil.isAssignable(bound, type, false)) {
PsiClass boundClass = bound instanceof PsiClassType ? ((PsiClassType)bound).resolve() : null;
@NonNls final String messageKey = boundClass == null || referenceClass.isInterface() == boundClass.isInterface()
? "generics.type.parameter.is.not.within.its.bound.extend"
: "generics.type.parameter.is.not.within.its.bound.implement";
String description = JavaErrorMessages.message(messageKey,
HighlightUtil.formatClass(referenceClass),
HighlightUtil.formatType(bound));
final HighlightInfo highlightInfo = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR,
typeElement2Highlight,
description);
if (bound instanceof PsiClassType) {
QuickFixAction
.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createExtendsListFix(referenceClass, (PsiClassType)bound, true),
null);
}
return highlightInfo;
}
}
return null;
}
private static String typeParameterListOwnerDescription(final PsiTypeParameterListOwner typeParameterListOwner) {
if (typeParameterListOwner instanceof PsiClass) {
return HighlightUtil.formatClass((PsiClass)typeParameterListOwner);
@@ -417,7 +435,7 @@ public class GenericsHighlightUtil {
public static HighlightInfo checkReferenceTypeUsedAsTypeArgument(PsiTypeElement typeElement) {
final PsiType type = typeElement.getType();
if (type instanceof PsiPrimitiveType ||
if (type != PsiType.NULL && type instanceof PsiPrimitiveType ||
type instanceof PsiWildcardType && ((PsiWildcardType)type).getBound() instanceof PsiPrimitiveType) {
final PsiElement element = new PsiMatcherImpl(typeElement)
.parent(PsiMatchers.hasClass(PsiReferenceParameterList.class))
@@ -1263,9 +1263,12 @@ public class HighlightMethodUtil {
return;
}
highlightInfo = GenericsHighlightUtil.checkGenericCallWithRawArguments(result, (PsiCallExpression)constructorCall);
}
if (highlightInfo != null) {
holder.add(highlightInfo);
if (highlightInfo != null) {
holder.add(highlightInfo);
}
if (PsiUtil.isLanguageLevel7OrHigher(constructorCall)) {
//check if not diamand - apply corresponding fix
}
}
}
}
@@ -21,7 +21,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.impl.light.LightClassReference;
import com.intellij.psi.impl.source.PsiClassReferenceType;
@@ -193,6 +192,9 @@ public class PsiImplUtil {
for (int i = 0; i < types.length; i++) {
types[i] = typeElements[i].getType();
}
if (types.length == 1 && types[0] instanceof PsiDiamondType) {
return ((PsiDiamondType)types[0]).getInferredTypes();
}
return types;
}
@@ -107,6 +107,10 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
element = element.getTreeNext();
continue;
}
else if (elementType == JavaElementType.DIAMOND_TYPE) {
cachedType = new PsiDiamondType(getManager(), this);
break;
}
else {
LOG.error("Unknown element type: " + elementType);
}
@@ -100,7 +100,7 @@ public class ClassBodyParsing extends Parsing {
}
// adding a reference, not simple tokens allows "Browse .." to work well
CompositeElement ref = parseJavaCodeReference(filterLexer, true, true, false);
CompositeElement ref = parseJavaCodeReference(filterLexer, true, true, false, false);
if (ref != null){
invalidElementsGroup.rawAddChildren(ref);
continue;
@@ -490,7 +490,7 @@ public class DeclarationParsing extends Parsing {
annotation.rawAddChildren(ParseUtil.createTokenElement(lexer, myContext.getCharTable()));
lexer.advance();
TreeElement classReference = parseJavaCodeReference(lexer, true, false, false);
TreeElement classReference = parseJavaCodeReference(lexer, true, false, false, false);
if (classReference != null) {
annotation.rawAddChildren(classReference);
}
@@ -1004,7 +1004,7 @@ public class DeclarationParsing extends Parsing {
}
// adding a reference, not simple tokens allows "Browse .." to work well
CompositeElement ref = parseJavaCodeReference(lexer, true, true, false);
CompositeElement ref = parseJavaCodeReference(lexer, true, true, false, false);
if (ref != null){
invalidElementsGroup.rawAddChildren(ref);
}
@@ -1043,7 +1043,7 @@ public class DeclarationParsing extends Parsing {
lexer.advance();
while (true) {
TreeElement classReference = parseJavaCodeReference(lexer, true, true, true);
TreeElement classReference = parseJavaCodeReference(lexer, true, true, true, false);
if (classReference == null) {
classReference = Factory.createErrorElement(JavaErrorMessages.message("expected.identifier"));
}
@@ -457,7 +457,7 @@ public class ExpressionParsing extends Parsing {
IElementType tokenType = lexer.getTokenType();
if (tokenType == JavaTokenType.LT) {
final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false);
final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false, false);
CompositeElement element1 = ASTFactory.composite(JavaElementType.REFERENCE_EXPRESSION);
element1.rawAddChildren(element);
element1.rawAddChildren(dot);
@@ -494,7 +494,7 @@ public class ExpressionParsing extends Parsing {
&& element.getElementType() == JavaElementType.REFERENCE_EXPRESSION) {
lexer.restore(startPos);
CompositeElement element1 = parseJavaCodeReference(lexer, false, true, false); // don't eat the last dot before "this" or "super"!
CompositeElement element1 = parseJavaCodeReference(lexer, false, true, false, false); // don't eat the last dot before "this" or "super"!
if (element1 == null || lexer.getTokenType() != JavaTokenType.DOT || lexer.getTokenStart() != pos.getOffset()) {
lexer.restore(pos);
return element;
@@ -522,7 +522,7 @@ public class ExpressionParsing extends Parsing {
element = element1;
}
else {
final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false);
final TreeElement referenceParameterList = parseReferenceParameterList(lexer, false, false);
CompositeElement element1 = ASTFactory.composite(JavaElementType.REFERENCE_EXPRESSION);
element1.rawAddChildren(element);
element1.rawAddChildren(dot);
@@ -731,6 +731,11 @@ public class ExpressionParsing extends Parsing {
return null;
}
protected boolean areDiamondsSupported() {
return myContext.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_7);
}
private CompositeElement parseNewExpression(Lexer lexer,
TreeElement qualifier,
TreeElement dot) {
@@ -746,7 +751,7 @@ public class ExpressionParsing extends Parsing {
TreeElement newKeyword = ParseUtil.createTokenElement(lexer, myContext.getCharTable());
element.rawAddChildren(newKeyword);
lexer.advance();
element.rawAddChildren(parseReferenceParameterList(lexer, false));
element.rawAddChildren(parseReferenceParameterList(lexer, false, areDiamondsSupported()));
boolean isPrimitive;
TreeElement refOrType;
@@ -754,7 +759,7 @@ public class ExpressionParsing extends Parsing {
if (lexer.getTokenType() == JavaTokenType.IDENTIFIER || parseAnnotations) {
isPrimitive = false;
refOrType = parseJavaCodeReference(lexer, true, true, parseAnnotations);
refOrType = parseJavaCodeReference(lexer, true, true, parseAnnotations, areDiamondsSupported());
}
else if (lexer.getTokenType() != null && ElementType.PRIMITIVE_TYPE_BIT_SET.contains(lexer.getTokenType())) {
isPrimitive = true;
@@ -835,7 +840,7 @@ public class ExpressionParsing extends Parsing {
private CompositeElement parseClassObjectAccessExpression(Lexer lexer) {
final LexerPosition pos = lexer.getCurrentPosition();
CompositeElement type = parseType(lexer, false, false); // don't eat last dot before "class"!
CompositeElement type = parseType(lexer, false, false, false); // don't eat last dot before "class"!
if (type == null) return null;
if (lexer.getTokenType() != JavaTokenType.DOT) {
lexer.restore(pos);
@@ -116,7 +116,7 @@ public class FileTextParsing extends Parsing {
packageStatement.rawAddChildren(ParseUtil.createTokenElement(lexer, myContext.getCharTable()));
lexer.advance();
TreeElement packageReference = parseJavaCodeReference(lexer, true, false, false);
TreeElement packageReference = parseJavaCodeReference(lexer, true, false, false, false);
if (packageReference == null) {
lexer.restore(startPos);
return null;
@@ -90,7 +90,7 @@ public class ImportsTextParsing extends Parsing {
return statement;
}
CompositeElement refElement = parseJavaCodeReference(lexer, true, false, false);
CompositeElement refElement = parseJavaCodeReference(lexer, true, false, false, false);
final TreeElement refParameterList = refElement.getLastChildNode();
if (refParameterList.getTreePrev().getElementType() == TokenType.ERROR_ELEMENT){
final ASTNode qualifier = refElement.findChildByRole(ChildRole.QUALIFIER);
@@ -67,7 +67,7 @@ public class JavadocParsing extends Parsing {
element = parseTypeWithEllipsis(lexer, true, false);
}
else{
element = myContext.getStatementParsing().parseJavaCodeReference(lexer, true, true, false);
element = myContext.getStatementParsing().parseJavaCodeReference(lexer, true, true, false, false);
}
if (element != null){
@@ -61,7 +61,7 @@ public class Parsing {
lexer.start(buffer, startOffset, endOffset);
JavaParsingContext context = new JavaParsingContext(table, LanguageLevelProjectExtension.getInstance(manager.getProject()).getLanguageLevel());
CompositeElement ref = context.getStatementParsing().parseJavaCodeReference(lexer, false, true, false);
CompositeElement ref = context.getStatementParsing().parseJavaCodeReference(lexer, false, true, false, false);
final FileElement dummyRoot = DummyHolderFactory.createHolder(manager, null, table).getTreeElement();
if (ref == null) {
if (!eatAll) return null;
@@ -85,7 +85,7 @@ public class Parsing {
}
public CompositeElement parseJavaCodeReference(Lexer lexer, boolean allowIncomplete, final boolean parseParameterList,
boolean parseAnnotations) {
boolean parseAnnotations, boolean parseNewExpression) {
CompositeElement refElement = ASTFactory.composite(JavaElementType.JAVA_CODE_REFERENCE);
LexerPosition beforeAnnos = lexer.getCurrentPosition();
if (parseAnnotations) {
@@ -102,7 +102,7 @@ public class Parsing {
refElement.rawAddChildren(identifier);
CompositeElement parameterList;
if (parseParameterList) {
parameterList = parseReferenceParameterList(lexer, true);
parameterList = parseReferenceParameterList(lexer, true, parseNewExpression);
}
else {
parameterList = ASTFactory.composite(JavaElementType.REFERENCE_PARAMETER_LIST);
@@ -136,7 +136,7 @@ public class Parsing {
refElement1.rawAddChildren(identifier);
CompositeElement parameterList1;
if (parseParameterList) {
parameterList1 = parseReferenceParameterList(lexer, true);
parameterList1 = parseReferenceParameterList(lexer, true, parseNewExpression);
}
else {
parameterList1 = ASTFactory.composite(JavaElementType.REFERENCE_PARAMETER_LIST);
@@ -148,14 +148,14 @@ public class Parsing {
return refElement;
}
public CompositeElement parseReferenceParameterList(Lexer lexer, boolean allowWildcard) {
public CompositeElement parseReferenceParameterList(Lexer lexer, boolean allowWildcard, boolean allowDiamonds) {
final CompositeElement list = ASTFactory.composite(JavaElementType.REFERENCE_PARAMETER_LIST);
if (lexer.getTokenType() != JavaTokenType.LT) return list;
final TreeElement lt = ParseUtil.createTokenElement(lexer, myContext.getCharTable());
list.rawAddChildren(lt);
lexer.advance();
while (true) {
final CompositeElement typeElement = parseType(lexer, true, allowWildcard);
final CompositeElement typeElement = parseType(lexer, true, allowWildcard, allowDiamonds);
if (typeElement != null) {
list.rawAddChildren(typeElement);
}
@@ -199,7 +199,7 @@ public class Parsing {
}
public CompositeElement parseTypeWithEllipsis(Lexer lexer, boolean eatLastDot, boolean allowWilcard) {
CompositeElement type = parseType(lexer, eatLastDot, allowWilcard);
CompositeElement type = parseType(lexer, eatLastDot, allowWilcard, false);
if (type == null) return null;
if (lexer.getTokenType() == JavaTokenType.ELLIPSIS) {
CompositeElement type1 = ASTFactory.composite(JavaElementType.TYPE);
@@ -217,7 +217,7 @@ public class Parsing {
}
public CompositeElement parseType(Lexer lexer){
return parseType(lexer, true, true);
return parseType(lexer, true, true, false);
}
protected void parseAnnotationListTo(@NotNull Lexer lexer, @Nullable CompositeElement element) {
@@ -229,7 +229,7 @@ public class Parsing {
}
}
public CompositeElement parseType(Lexer lexer, boolean eatLastDot, boolean allowWildcard){
public CompositeElement parseType(Lexer lexer, boolean eatLastDot, boolean allowWildcard, boolean allowDiamonds){
IElementType tokenType = lexer.getTokenType();
if (tokenType == null) {
return null;
@@ -244,11 +244,16 @@ public class Parsing {
lexer.advance();
}
else if (tokenType == JavaTokenType.IDENTIFIER){
refElement = parseJavaCodeReference(lexer, eatLastDot, true, false);
refElement = parseJavaCodeReference(lexer, eatLastDot, true, false, allowDiamonds);
}
else if (allowWildcard && lexer.getTokenType() == JavaTokenType.QUEST) {
return parseWildcardType(lexer);
}
else if (allowDiamonds && lexer.getTokenType() == JavaTokenType.GT) {
final CompositeElement typeElement = ASTFactory.composite(JavaElementType.TYPE);
typeElement.rawAddChildren(ASTFactory.composite(JavaElementType.DIAMOND_TYPE));
return typeElement;
}
else {
return null;
}
@@ -304,7 +309,7 @@ public class Parsing {
if (lexer.getTokenType() == JavaTokenType.SUPER_KEYWORD || lexer.getTokenType() == JavaTokenType.EXTENDS_KEYWORD) {
type.rawAddChildren(ParseUtil.createTokenElement(lexer, myContext.getCharTable()));
lexer.advance();
CompositeElement boundType = parseType(lexer, true, false);
CompositeElement boundType = parseType(lexer, true, false, false);
if (boundType != null) {
type.rawAddChildren(boundType);
}
@@ -358,7 +358,7 @@ public class StatementParsing extends Parsing {
declStatement.rawAddChildren(decl);
}
else {
final CompositeElement type = parseType(lexer, false, false);
final CompositeElement type = parseType(lexer, false, false, false);
if (type != null) declStatement.rawAddChildren(type);
final CompositeElement errorElement = Factory.createErrorElement(JavaErrorMessages.message("expected.identifier"));
declStatement.rawAddChildren(errorElement);
@@ -67,6 +67,7 @@ public interface JavaElementType {
IElementType IMPORT_STATIC_REFERENCE = new IJavaElementType("IMPORT_STATIC_REFERENCE");
IElementType TYPE = new IJavaElementType("TYPE");
IElementType DIAMOND_TYPE = new IJavaElementType("DIAMOND_TYPE");
IElementType REFERENCE_PARAMETER_LIST = new IJavaElementType("REFERENCE_PARAMETER_LIST", true);
IElementType JAVA_CODE_REFERENCE = new IJavaElementType("JAVA_CODE_REFERENCE");
IElementType PACKAGE_STATEMENT = new IJavaElementType("PACKAGE_STATEMENT");
@@ -604,13 +604,7 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
public PsiType[] getTypeParameters() {
final PsiReferenceParameterList parameterList = getParameterList();
if (parameterList == null) return PsiType.EMPTY_ARRAY;
PsiTypeElement[] typeElements = parameterList.getTypeParameterElements();
PsiType[] types = new PsiType[typeElements.length];
for (int i = 0; i < types.length; i++) {
types[i] = typeElements[i].getType();
}
return types;
return parameterList.getTypeArguments();
}
@@ -0,0 +1,38 @@
class Neg01<X extends Number> {
Neg01(X x) {
}
<Z> Neg01(X x, Z z) {
}
void test() {
Neg01<<error>String</error>> n1 = new Neg01<<error></error>>("" ); //new Foo<Integer> created
Neg01<? extends String> n2 = new Neg01<<error></error>>(""); //new Foo<Integer> created
Neg01<?> n3 = new Neg01<><error>("")</error>; //new Foo<Object> created
Neg01<? super String> n4 = new Neg01<<error></error>>(""); //new Foo<Object> created
Neg01<<error>String</error>> n5 = new Neg01<<error></error>>("") {
}; //new Foo<Integer> created
Neg01<? extends String> n6 = new Neg01<<error></error>>("") {
}; //new Foo<Integer> created
Neg01<?> n7 = new Neg01<><error>("")</error> {
}; //new Foo<Object> created
Neg01<? super String> n8 = new Neg01<<error></error>>("") {
}; //new Foo<Object> created
Neg01<<error>String</error>> n9 = new Neg01<<error></error>>("", ""); //new Foo<Integer> created
Neg01<? extends String> n10 = new Neg01<<error></error>>("", ""); //new Foo<Integer> created
Neg01<?> n11 = new Neg01<><error>("", "")</error>; //new Foo<Object> created
<error>Foo</error><? super String> n12 = new Neg01<<error></error>>("", ""); //new Foo<Object> created
Neg01<<error>String</error>> n13 = new Neg01<<error></error>>("", "") {
}; //new Foo<Integer> created
Neg01<? extends String> n14 = new Neg01<<error></error>>("", "") {
}; //new Foo<Integer> created
Neg01<?> n15 = new Neg01<><error>("", "")</error> {
}; //new Foo<Object> created
Neg01<? super String> n16 = new Neg01<<error></error>>("", "") {
}; //new Foo<Object> created
}
}
@@ -0,0 +1,71 @@
class Neg02 {
static class Foo<X extends Number> {
Foo(X x) {
}
<Z> Foo(X x, Z z) {
}
}
void testSimple() {
Foo<<error>String</error>> f1 = new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<? extends String> f2 = new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<?> f3 = new Foo<><error>("")</error>; //new Foo<Object> created
Foo<? super String> f4 = new Foo<<error></error>>(""); //new Foo<Object> created
Foo<<error>String</error>> f5 = new Foo<<error></error>>("") {
}; //new Foo<Integer> created
Foo<? extends String> f6 = new Foo<<error></error>>("") {
}; //new Foo<Integer> created
Foo<?> f7 = new Foo< ><error>("")</error> {
}; //new Foo<Object> created
Foo<? super String> f8 = new Foo<<error></error>>("") {
}; //new Foo<Object> created
Foo<<error>String</error>> f9 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<? extends String> f10 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<?> f11 = new Foo< ><error>("", "")</error>; //new Foo<Object> created
Foo<? super String> f12 = new Foo<<error></error>>("", ""); //new Foo<Object> created
Foo<<error>String</error>> f13 = new Foo<<error></error>>("", "") {
}; //new Foo<Integer> created
Foo<? extends String> f14 = new Foo<<error></error>>("", "") {
}; //new Foo<Integer> created
Foo<?> f15 = new Foo< ><error>("", "")</error> {
}; //new Foo<Object> created
Foo<? super String> f16 = new Foo<<error></error>>("", "") {
}; //new Foo<Object> created
}
void testQualified() {
Foo<<error>String</error>> f1 = new Neg02.Foo<<error></error>>(""); //new Foo<Integer> created
Foo<? extends String> f2 = new Neg02.Foo<<error></error>>(""); //new Foo<Integer> created
Foo<?> f3 = new Neg02.Foo< ><error>("")</error>; //new Foo<Object> created
Foo<? super String> f4 = new Neg02.Foo<<error></error>>(""); //new Foo<Object> created
Foo<<error>String</error>> f5 = new Neg02.Foo<<error></error>>("") {
}; //new Foo<Integer> created
Foo<? extends String> f6 = new Neg02.Foo<<error></error>>("") {
}; //new Foo<Integer> created
Foo<?> f7 = new Neg02.Foo< ><error>("")</error> {
}; //new Foo<Object> created
Foo<? super String> f8 = new Neg02.Foo<<error></error>>("") {
}; //new Foo<Object> created
Foo<<error>String</error>> f9 = new Neg02.Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<? extends String> f10 = new Neg02.Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<?> f11 = new Neg02.Foo< ><error>("", "")</error>; //new Foo<Object> created
Foo<? super String> f12 = new Neg02.Foo<<error></error>>("", ""); //new Foo<Object> created
Foo<<error>String</error>> f13 = new Neg02.Foo<<error></error>>("", "") {
}; //new Foo<Integer> created
Foo<? extends String> f14 = new Neg02.Foo<<error></error>>("", "") {
}; //new Foo<Integer> created
Foo<?> f15 = new Neg02.Foo< ><error>("", "")</error> {
}; //new Foo<Object> created
Foo<? super String> f16 = new Neg02.Foo<<error></error>>("", "") {
}; //new Foo<Object> created
}
}
@@ -0,0 +1,73 @@
class Neg03<U> {
class Foo<V extends Number> {
Foo(V x) {}
<Z> Foo(V x, Z z) {}
}
void testSimple() {
Foo<<error>String</error>> f1 = new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<? extends String> f2 = new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<?> f3 = new Foo<><error>("")</error>; //new Foo<Object> created
Foo<? super String> f4 = new Foo<<error></error>>(""); //new Foo<Object> created
Foo<<error>String</error>> f5 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<? extends String> f6 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<?> f7 = new Foo<><error>("")</error>{}; //new Foo<Object> created
Foo<? super String> f8 = new Foo<<error></error>>(""){}; //new Foo<Object> created
Foo<<error>String</error>> f9 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<? extends String> f10 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<?> f11 = new Foo<><error>("", "")</error>; //new Foo<Object> created
Foo<? super String> f12 = new Foo<<error></error>>("", ""); //new Foo<Object> created
Foo<<error>String</error>> f13 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<? extends String> f14 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<?> f15 = new Foo<><error>("", "")</error>{}; //new Foo<Object> created
Foo<? super String> f16 = new Foo<<error></error>>("", ""){}; //new Foo<Object> created
}
void testQualified_1() {
Foo<<error>String</error>> f1 = new Neg03<U>.Foo<<error></error>>(""); //new Foo<Integer> created
Foo<? extends String> f2 = new Neg03<U>.Foo<<error></error>>(""); //new Foo<Integer> created
Foo<?> f3 = new Neg03<U>.Foo<><error>("")</error>; //new Foo<Object> created
Foo<? super String> f4 = new Neg03<U>.Foo<<error></error>>(""); //new Foo<Object> created
Foo<<error>String</error>> f5 = new Neg03<U>.Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<? extends String> f6 = new Neg03<U>.Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<?> f7 = new Neg03<U>.Foo<><error>("")</error>{}; //new Foo<Object> created
Foo<? super String> f8 = new Neg03<U>.Foo<<error></error>>(""){}; //new Foo<Object> created
Foo<<error>String</error>> f9 = new Neg03<U>.Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<? extends String> f10 = new Neg03<U>.Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<?> f11 = new Neg03<U>.Foo<><error>("", "")</error>; //new Foo<Object> created
Foo<? super String> f12 = new Neg03<U>.Foo<<error></error>>("", ""); //new Foo<Object> created
Foo<<error>String</error>> f13 = new Neg03<U>.Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<? extends String> f14 = new Neg03<U>.Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<?> f15 = new Neg03<U>.Foo<><error>("", "")</error>{}; //new Foo<Object> created
Foo<? super String> f16 = new Neg03<U>.Foo<<error></error>>("", ""){}; //new Foo<Object> created
}
void testQualified_2(Neg03<U> n) {
Foo<<error>String</error>> f1 = n.new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<? extends String> f2 = n.new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<?> f3 = n.new Foo<><error>("")</error>; //new Foo<Integer> created
Foo<? super String> f4 = n.new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<<error>String</error>> f5 = n.new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<? extends String> f6 = n.new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<?> f7 = n.new Foo<><error>("")</error>{}; //new Foo<Integer> created
Foo<? super String> f8 = n.new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<<error>String</error>> f9 = n.new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<? extends String> f10 = n.new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<?> f11 = n.new Foo<><error>("", "")</error>; //new Foo<Integer> created
Foo<? super String> f12 = n.new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<<error>String</error>> f13 = n.new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<? extends String> f14 = n.new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<?> f15 = n.new Foo<><error>("", "")</error>{}; //new Foo<Integer> created
Foo<? super String> f16 = n.new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
}
}
@@ -0,0 +1,28 @@
class Neg04 {
void test() {
class Foo<V extends Number> {
Foo(V x) {}
<Z> Foo(V x, Z z) {}
}
Foo<<error>String</error>> n1 = new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<? extends String> n2 = new Foo<<error></error>>(""); //new Foo<Integer> created
Foo<?> n3 = new Foo<><error>("")</error>; //new Foo<Object> created
Foo<? super String> n4 = new Foo<<error></error>>(""); //new Foo<Object> created
Foo<<error>String</error>> n5 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<? extends String> n6 = new Foo<<error></error>>(""){}; //new Foo<Integer> created
Foo<?> n7 = new Foo<><error>("")</error>{}; //new Foo<Object> created
Foo<? super String> n8 = new Foo<<error></error>>(""){}; //new Foo<Object> created
Foo<<error>String</error>> n9 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<? extends String> n10 = new Foo<<error></error>>("", ""); //new Foo<Integer> created
Foo<?> n11 = new Foo<><error>("", "")</error>; //new Foo<Object> created
Foo<? super String> n12 = new Foo<<error></error>>("", ""); //new Foo<Object> created
Foo<<error>String</error>> n13 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<? extends String> n14 = new Foo<<error></error>>("", ""){}; //new Foo<Integer> created
Foo<?> n15 = new Foo<><error>("", "")</error>{}; //new Foo<Object> created
Foo<? super String> n16 = new Foo<<error></error>>("", ""){}; //new Foo<Object> created
}
}
@@ -0,0 +1,51 @@
class Neg05<U> {
class Foo<V> {
Foo(V x) {}
<Z> Foo(V x, Z z) {}
}
void testRare_1() {
Neg05<?>.Foo<String> f1 = new Neg05.Foo<error><></error>(""); //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f2 = new Neg05.Foo<error><></error>(""); //new Foo<Integer> created
Neg05<?>.Foo<?> f3 = new Neg05.Foo<error><></error>(""); //new Foo<Object> created
Neg05<?>.Foo<? super String> f4 = new Neg05.Foo<error><></error>(""); //new Foo<Object> created
Neg05<?>.Foo<String> f5 = new Neg05.Foo<error><></error>(""){}; //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f6 = new Neg05.Foo<error><></error>(""){}; //new Foo<Integer> created
Neg05<?>.Foo<?> f7 = new Neg05.Foo<error><></error>(""){}; //new Foo<Object> created
Neg05<?>.Foo<? super String> f8 = new Neg05.Foo<error><></error>(""){}; //new Foo<Object> created
Neg05<?>.Foo<String> f9 = new Neg05.Foo<error><></error>("", ""); //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f10 = new Neg05.Foo<error><></error>("", ""); //new Foo<Integer> created
Neg05<?>.Foo<?> f11 = new Neg05.Foo<error><></error>("", ""); //new Foo<Object> created
Neg05<?>.Foo<? super String> f12 = new Neg05.Foo<error><></error>("", ""); //new Foo<Object> created
Neg05<?>.Foo<String> f13 = new Neg05.Foo<error><></error>("", ""){}; //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f14 = new Neg05.Foo<error><></error>("", ""){}; //new Foo<Integer> created
Neg05<?>.Foo<?> f15 = new Neg05.Foo<error><></error>("", ""){}; //new Foo<Object> created
Neg05<?>.Foo<? super String> f16 = new Neg05.Foo<error><></error>("", ""){}; //new Foo<Object> created
}
void testRare_2(Neg05 n) {
Neg05<?>.Foo<String> f1 = n.new Foo<error><></error>(""); //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f2 = n.new Foo<error><></error>(""); //new Foo<Integer> created
Neg05<?>.Foo<?> f3 = n.new Foo<error><></error>(""); //new Foo<Integer> created
Neg05<?>.Foo<? super String> f4 = n.new Foo<error><></error>(""); //new Foo<Integer> created
Neg05<?>.Foo<String> f5 = n.new Foo<error><></error>(""){}; //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f6 = n.new Foo<error><></error>(""){}; //new Foo<Integer> created
Neg05<?>.Foo<?> f7 = n.new Foo<error><></error>(""){}; //new Foo<Integer> created
Neg05<?>.Foo<? super String> f8 = n.new Foo<error><></error>(""){}; //new Foo<Integer> created
Neg05<?>.Foo<String> f9 = n.new Foo<error><></error>("", ""); //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f10 = n.new Foo<error><></error>("", ""); //new Foo<Integer> created
Neg05<?>.Foo<?> f11 = n.new Foo<error><></error>("", ""); //new Foo<Integer> created
Neg05<?>.Foo<? super String> f12 = n.new Foo<error><></error>("", ""); //new Foo<Integer> created
Neg05<?>.Foo<String> f13 = n.new Foo<error><></error>("", ""){}; //new Foo<Integer> created
Neg05<?>.Foo<? extends String> f14 = n.new Foo<error><></error>("", ""){}; //new Foo<Integer> created
Neg05<?>.Foo<?> f15 = n.new Foo<error><></error>("", ""){}; //new Foo<Integer> created
Neg05<?>.Foo<? super String> f16 = n.new Foo<error><></error>("", ""){}; //new Foo<Integer> created
}
}
@@ -0,0 +1,33 @@
public class Pos01<X> {
Pos01(X x) {}
<Z> Pos01(X x, Z z) {}
void test() {
Pos01<Integer> p1 = new Pos01<>(1); //new Foo<Integer> created
Pos01<? extends Integer> p2 = new Pos01<>(1); //new Foo<Integer> created
Pos01<?> p3 = new Pos01<>(1); //new Foo<Object> created
Pos01<? super Integer> p4 = new Pos01<>(1); //new Foo<Object> created
Pos01<Integer> p5 = new Pos01<>(1){}; //new Foo<Integer> created
Pos01<? extends Integer> p6 = new Pos01<>(1){}; //new Foo<Integer> created
Pos01<?> p7 = new Pos01<>(1){}; //new Foo<Object> created
Pos01<? super Integer> p8 = new Pos01<>(1){}; //new Foo<Object> created
Pos01<Integer> p9 = new Pos01<>(1, ""); //new Foo<Integer> created
Pos01<? extends Integer> p10 = new Pos01<>(1, ""); //new Foo<Integer> created
Pos01<?> p11 = new Pos01<>(1, ""); //new Foo<Object> created
Pos01<? super Integer> p12 = new Pos01<>(1, ""); //new Foo<Object> created
Pos01<Integer> p13 = new Pos01<>(1, ""){}; //new Foo<Integer> created
Pos01<? extends Integer> p14= new Pos01<>(1, ""){}; //new Foo<Integer> created
Pos01<?> p15 = new Pos01<>(1, ""){}; //new Foo<Object> created
Pos01<? super Integer> p16 = new Pos01<>(1, ""){}; //new Foo<Object> created
}
public static void main(String[] args) {
Pos01<String> p1 = new Pos01<>("");
p1.test();
}
}
@@ -0,0 +1,57 @@
public class Pos02 {
static class Foo<X> {
Foo(X x) {}
<Z> Foo(X x, Z z) {}
}
void testSimple() {
Foo<Integer> f1 = new Foo<>(1); //new Foo<Integer> created
Foo<? extends Integer> f2 = new Foo<>(1); //new Foo<Integer> created
Foo<?> f3 = new Foo<>(1); //new Foo<Object> created
Foo<? super Integer> f4 = new Foo<>(1); //new Foo<Object> created
Foo<Integer> f5 = new Foo<>(1){}; //new Foo<Integer> created
Foo<? extends Integer> f6 = new Foo<>(1){}; //new Foo<Integer> created
Foo<?> f7 = new Foo<>(1){}; //new Foo<Object> created
Foo<? super Integer> f8 = new Foo<>(1){}; //new Foo<Object> created
Foo<Integer> f9 = new Foo<>(1, ""); //new Foo<Integer> created
Foo<? extends Integer> f10 = new Foo<>(1, ""); //new Foo<Integer> created
Foo<?> f11 = new Foo<>(1, ""); //new Foo<Object> created
Foo<? super Integer> f12 = new Foo<>(1, ""); //new Foo<Object> created
Foo<Integer> f13 = new Foo<>(1, ""){}; //new Foo<Integer> created
Foo<? extends Integer> f14 = new Foo<>(1, ""){}; //new Foo<Integer> created
Foo<?> f15 = new Foo<>(1, ""){}; //new Foo<Object> created
Foo<? super Integer> f16 = new Foo<>(1, ""){}; //new Foo<Object> created
}
void testQualified() {
Foo<Integer> f1 = new Pos02.Foo<>(1); //new Foo<Integer> created
Foo<? extends Integer> f2 = new Pos02.Foo<>(1); //new Foo<Integer> created
Foo<?> f3 = new Pos02.Foo<>(1); //new Foo<Object> created
Foo<? super Integer> f4 = new Pos02.Foo< >(1); //new Foo<Object> created
Foo<Integer> f5 = new Pos02.Foo<>(1){}; //new Foo<Integer> created
Foo<? extends Integer> f6 = new Pos02.Foo<>(1){}; //new Foo<Integer> created
Foo<?> f7 = new Pos02.Foo<>(1){}; //new Foo<Object> created
Foo<? super Integer> f8 = new Pos02.Foo<>(1){}; //new Foo<Object> created
Foo<Integer> f9 = new Pos02.Foo<>(1, ""); //new Foo<Integer> created
Foo<? extends Integer> f10 = new Pos02.Foo<>(1, ""); //new Foo<Integer> created
Foo<?> f11 = new Pos02.Foo<>(1, ""); //new Foo<Object> created
Foo<? super Integer> f12 = new Pos02.Foo<>(1, ""); //new Foo<Object> created
Foo<Integer> f13 = new Pos02.Foo<>(1, ""){}; //new Foo<Integer> created
Foo<? extends Integer> f14 = new Pos02.Foo<>(1, ""){}; //new Foo<Integer> created
Foo<?> f15 = new Pos02.Foo<>(1, ""){}; //new Foo<Object> created
Foo<? super Integer> f16 = new Pos02.Foo<>(1, ""){}; //new Foo<Object> created
}
public static void main(String[] args) {
Pos02 p2 = new Pos02();
p2.testSimple();
p2.testQualified();
}
}
@@ -0,0 +1,80 @@
public class Pos03<U> {
class Foo<V> {
Foo(V x) {}
<Z> Foo(V x, Z z) {}
}
void testSimple() {
Foo<Integer> f1 = new Foo<>(1); //new Foo<Integer> created
Foo<? extends Integer> f2 = new Foo<>(1); //new Foo<Integer> created
Foo<?> f3 = new Foo<>(1); //new Foo<Object> created
Foo<? super Integer> f4 = new Foo<>(1); //new Foo<Object> created
Foo<Integer> f5 = new Foo<>(1){}; //new Foo<Integer> created
Foo<? extends Integer> f6 = new Foo<>(1){}; //new Foo<Integer> created
Foo<?> f7 = new Foo<>(1){}; //new Foo<Object> created
Foo<? super Integer> f8 = new Foo<>(1){}; //new Foo<Object> created
Foo<Integer> f9 = new Foo<>(1, ""); //new Foo<Integer> created
Foo<? extends Integer> f10 = new Foo<>(1, ""); //new Foo<Integer> created
Foo<?> f11 = new Foo<>(1, ""); //new Foo<Object> created
Foo<? super Integer> f12 = new Foo<>(1, ""); //new Foo<Object> created
Foo<Integer> f13 = new Foo<>(1, ""){}; //new Foo<Integer> created
Foo<? extends Integer> f14 = new Foo<>(1, ""){}; //new Foo<Integer> created
Foo<?> f15 = new Foo<>(1, ""){}; //new Foo<Object> created
Foo<? super Integer> f16 = new Foo<>(1, ""){}; //new Foo<Object> created
}
void testQualified_1() {
Foo<Integer> f1 = new Pos03<U>.Foo<>(1); //new Foo<Integer> created
Foo<? extends Integer> f2 = new Pos03<U>.Foo<>(1); //new Foo<Integer> created
Foo<?> f3 = new Pos03<U>.Foo<>(1); //new Foo<Object> created
Foo<? super Integer> f4 = new Pos03<U>.Foo<>(1); //new Foo<Object> created
Foo<Integer> f5 = new Pos03<U>.Foo<>(1){}; //new Foo<Integer> created
Foo<? extends Integer> f6 = new Pos03<U>.Foo<>(1){}; //new Foo<Integer> created
Foo<?> f7 = new Pos03<U>.Foo<>(1){}; //new Foo<Object> created
Foo<? super Integer> f8 = new Pos03<U>.Foo<>(1){}; //new Foo<Object> created
Foo<Integer> f9 = new Pos03<U>.Foo<>(1, ""); //new Foo<Integer> created
Foo<? extends Integer> f10 = new Pos03<U>.Foo<>(1, ""); //new Foo<Integer> created
Foo<?> f11 = new Pos03<U>.Foo<>(1, ""); //new Foo<Object> created
Foo<? super Integer> f12 = new Pos03<U>.Foo<>(1, ""); //new Foo<Object> created
Foo<Integer> f13 = new Pos03<U>.Foo<>(1, ""){}; //new Foo<Integer> created
Foo<? extends Integer> f14 = new Pos03<U>.Foo<>(1, ""){}; //new Foo<Integer> created
Foo<?> f15 = new Pos03<U>.Foo<>(1, " "){}; //new Foo<Object> created
Foo<? super Integer> f16 = new Pos03<U>.Foo<>(1, ""){}; //new Foo<Object> created
}
void testQualified_2(Pos03<U> p) {
Foo<Integer> f1 = p.new Foo<>(1); //new Foo<Integer> created
Foo<? extends Integer> f2 = p.new Foo<>( 1); //new Foo<Integer> created
Foo<?> f3 = p.new Foo<>(1); //new Foo<Object> created
Foo<? super Integer> f4 = p.new Foo<>(1); //new Foo<Object> created
Foo<Integer> f5 = p.new Foo<>(1){}; //new Foo<Integer> created
Foo<? extends Integer> f6 = p.new Foo<>(1){}; //new Foo<Integer> created
Foo<?> f7 = p.new Foo<>(1){}; //new Foo<Object> created
Foo<? super Integer> f8 = p.new Foo<>(1){}; //new Foo<Object> created
Foo<Integer> f9 = p.new Foo<>(1, ""); //new Foo<Integer> created
Foo<? extends Integer> f10 = p.new Foo<>(1, ""); //new Foo<Integer> created
Foo<?> f11 = p.new Foo<>(1, ""); //new Foo<Object> created
Foo<? super Integer> f12 = p.new Foo<>(1, ""); //new Foo<Object> created
Foo<Integer> f13 = p.new Foo<>(1, ""){}; //new Foo<Integer> created
Foo<? extends Integer> f14 = p.new Foo<>(1, ""){}; //new Foo<Integer> created
Foo<?> f15 = p.new Foo<>(1, ""){}; //new Foo<Object> created
Foo<? super Integer> f16 = p.new Foo<>(1, ""){}; //new Foo<Object> created
}
public static void main(String[] args) {
Pos03<String> p3 = new Pos03<>( );
p3.testSimple();
p3.testQualified_1();
p3.testQualified_2(p3);
}
}
@@ -0,0 +1,44 @@
public class Pos04<U> {
void test() {
class Foo<V> {
Foo(V x) {
}
<Z> Foo(V x, Z z) {
}
}
Foo<Integer> p1 = new Foo< >(1); //new Foo<Integer> created
Foo<? extends Integer> p2 = new Foo< >(1); //new Foo<Integer> created
Foo<?> p3 = new Foo< >(1); //new Foo<Object> created
Foo<? super Integer> p4 = new Foo< >(1); //new Foo<Object> created
Foo<Integer> p5 = new Foo< >(1) {
}; //new Foo<Integer> created
Foo<? extends Integer> p6 = new Foo< >(1) {
}; //new Foo<Integer> created
Foo<?> p7 = new Foo< >(1) {
}; //new Foo<Object> created
Foo<? super Integer> p8 = new Foo< >(1) {
}; //new Foo<Object> created
Foo<Integer> p9 = new Foo< >(1, ""); //new Foo<Integer> created
Foo<? extends Integer> p10 = new Foo< >(1, ""); //new Foo<Integer> created
Foo<?> p11 = new Foo< >(1, ""); //new Foo<Object> created
Foo<? super Integer> p12 = new Foo< >(1, ""); //new Foo<Object> created
Foo<Integer> p13 = new Foo< >(1, "") {
}; //new Foo<Integer> created
Foo<? extends Integer> p14 = new Foo< >(1, "") {
}; //new Foo<Integer> created
Foo<?> p15 = new Foo< >(1, "") {
}; //new Foo<Object> created
Foo<? super Integer> p16 = new Foo< >(1, "") {
}; //new Foo<Object> created
}
public static void main(String[] args) {
Pos04<String> p4 = new Pos04<>();
p4.test();
}
}
@@ -16,4 +16,40 @@ public class LightAdvHighlightingJdk7Test extends LightDaemonAnalyzerTestCase {
public void testSwitchByString() throws Exception {
doTest(true, false);
}
public void testDiamondPos1() throws Exception {
doTest(false, false);
}
public void testDiamondPos2() throws Exception {
doTest(false, false);
}
public void testDiamondPos3() throws Exception {
doTest(false, false);
}
public void testDiamondPos4() throws Exception {
doTest(false, false);
}
public void testDiamondNeg1() throws Exception {
doTest(false, false);
}
public void testDiamondNeg2() throws Exception {
doTest(false, false);
}
public void testDiamondNeg3() throws Exception {
doTest(false, false);
}
public void testDiamondNeg4() throws Exception {
doTest(false, false);
}
public void testDiamondNeg5() throws Exception {
doTest(false, false);
}
}
@@ -0,0 +1,147 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* User: anna
* Date: Jul 30, 2010
*/
public class PsiDiamondType extends PsiType {
private static final PsiType[] NULL_TYPES = new PsiType[]{NULL};
private PsiManager myManager;
private final PsiTypeElement myTypeElement;
public PsiDiamondType(PsiManager manager, PsiTypeElement psiTypeElement) {
super(PsiAnnotation.EMPTY_ARRAY);
myManager = manager;
myTypeElement = psiTypeElement;
}
@Override
public String getPresentableText() {
return "";
}
@Override
public String getCanonicalText() {
return "";
}
@Override
public String getInternalCanonicalText() {
return "Diamond Type";
}
@Override
public boolean isValid() {
return false;
}
@Override
public boolean equalsToText(@NonNls String text) {
return text != null && text.isEmpty();
}
@Override
public <A> A accept(PsiTypeVisitor<A> visitor) {
return visitor.visitType(this);
}
@Override
public GlobalSearchScope getResolveScope() {
return GlobalSearchScope.allScope(myManager.getProject());
}
@NotNull
@Override
public PsiType[] getSuperTypes() {
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]).getType());
}
}
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).getType());
}
}
}
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()));
}
}
}
}
}
return NULL_TYPES;
}
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;
}
}
}
return types;
}
return NULL_TYPES;
}
}
@@ -119,7 +119,7 @@ public class TypeConversionUtil {
private static boolean isNarrowingReferenceConversionAllowed(PsiType fromType, PsiType toType) {
if (toType instanceof PsiPrimitiveType || fromType instanceof PsiPrimitiveType) return fromType.equals(toType);
//Done with primitives
if (toType instanceof PsiDiamondType || fromType instanceof PsiDiamondType) return false;
if (toType instanceof PsiArrayType && !(fromType instanceof PsiArrayType)) {
if (fromType instanceof PsiClassType) {
final PsiClass resolved = ((PsiClassType)fromType).resolve();