summaryrefslogtreecommitdiff
path: root/java/java-psi-api/src
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2013-04-01 14:41:51 -0700
committerJean-Baptiste Queru <jbq@google.com>2013-04-01 14:41:51 -0700
commit2bd2b7c2623d4266384e890271869efc044aabff (patch)
tree0b31f50e55975b6354ed458314e17b4441bb4e17 /java/java-psi-api/src
parent1d526b16d476792ca7ce47616d55833115e8d6ab (diff)
downloadidea-2bd2b7c2623d4266384e890271869efc044aabff.tar.gz
Snapshot ee98b298267d0e09d2cd2f0731b6480a56dd48e7 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I4515f72af131fdea9fc6905a4dc0fe9532409a81
Diffstat (limited to 'java/java-psi-api/src')
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java5
-rw-r--r--java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java7
-rw-r--r--java/java-psi-api/src/com/intellij/psi/LambdaUtil.java64
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiAnnotation.java18
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiAnnotationOwner.java11
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiArrayType.java8
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiClassType.java37
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiElementFactory.java21
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java11
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java11
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java5
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java7
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiNewExpression.java22
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java6
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiType.java75
-rw-r--r--java/java-psi-api/src/com/intellij/psi/PsiTypeElement.java3
-rw-r--r--java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java17
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java7
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java6
19 files changed, 240 insertions, 101 deletions
diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
index 1d6834be1dcb..1f91685ec32b 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -234,7 +234,8 @@ public class GenericsUtil {
}
@Nullable
- public static PsiType getVariableTypeByExpressionType(final PsiType type) {
+ public static PsiType getVariableTypeByExpressionType(@Nullable final PsiType type) {
+ if (type == null) return null;
PsiType transformed = type.accept(new PsiTypeVisitor<PsiType>() {
@Override
public PsiType visitArrayType(PsiArrayType arrayType) {
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java
index 07cc842b7e05..fc1d2957c2da 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaHighlightingUtil.java
@@ -28,9 +28,14 @@ import java.util.List;
public class LambdaHighlightingUtil {
@Nullable
public static String checkInterfaceFunctional(@NotNull PsiClass psiClass) {
+ return checkInterfaceFunctional(psiClass, "Target type of a lambda conversion must be an interface");
+ }
+
+ @Nullable
+ public static String checkInterfaceFunctional(@NotNull PsiClass psiClass, String interfaceNonFunctionalMessage) {
if (psiClass instanceof PsiTypeParameter) return null; //should be logged as cyclic inference
final List<MethodSignature> signatures = LambdaUtil.findFunctionCandidates(psiClass);
- if (signatures == null) return "Target type of a lambda conversion must be an interface";
+ if (signatures == null) return interfaceNonFunctionalMessage;
if (signatures.isEmpty()) return "No target method found";
if (signatures.size() == 1) {
final MethodSignature functionalMethod = signatures.get(0);
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index 672f290abbdc..d66962410665 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -652,7 +652,7 @@ public class LambdaUtil {
final PsiType interfaceReturnType1 = getReturnType(functionalInterfaceIdx, conflict);
if (actualParameterTypes[functionalInterfaceIdx] instanceof PsiLambdaExpressionType || actualParameterTypes[functionalInterfaceIdx] instanceof PsiMethodReferenceType) {
if (interfaceReturnType != null && interfaceReturnType1 != null && !Comparing.equal(interfaceReturnType, interfaceReturnType1)) {
- int moreSpecific1 = isMoreSpecific(interfaceReturnType, interfaceReturnType1);
+ int moreSpecific1 = isMoreSpecific(interfaceReturnType, interfaceReturnType1, actualParameterTypes[functionalInterfaceIdx]);
if (moreSpecific < 0 && moreSpecific1 > 0 || moreSpecific > 0 && moreSpecific1 < 0) {
moreSpecific = 0;
break;
@@ -676,22 +676,38 @@ public class LambdaUtil {
}
}
- private static int isMoreSpecific(PsiType returnType, PsiType returnType1) {
+ enum TypeKind {
+ PRIMITIVE, REFERENCE, NONE_DETERMINED
+ }
+
+ private static int isMoreSpecific(PsiType returnType, PsiType returnType1, PsiType lambdaType) {
if (returnType == PsiType.VOID || returnType1 == PsiType.VOID) return 0;
- if (returnType instanceof PsiPrimitiveType) {
- if (!(returnType1 instanceof PsiPrimitiveType)) {
- return -1;
- } else {
- return TypeConversionUtil.isAssignable(returnType, returnType1) ? 1 : -1;
+ TypeKind typeKind = TypeKind.PRIMITIVE;
+ if (lambdaType instanceof PsiLambdaExpressionType) {
+ typeKind = areLambdaReturnExpressionsPrimitive((PsiLambdaExpressionType)lambdaType);
+ } else if (lambdaType instanceof PsiMethodReferenceType) {
+ final PsiElement referencedElement = ((PsiMethodReferenceType)lambdaType).getExpression().resolve();
+ if (referencedElement instanceof PsiMethod && !(((PsiMethod)referencedElement).getReturnType() instanceof PsiPrimitiveType)) {
+ typeKind = TypeKind.REFERENCE;
+ }
+ }
+ if (typeKind != TypeKind.NONE_DETERMINED) {
+ if (returnType instanceof PsiPrimitiveType) {
+ final int moreSpecific = typeKind == TypeKind.PRIMITIVE ? 1 : -1;
+ if (!(returnType1 instanceof PsiPrimitiveType)) {
+ return -moreSpecific;
+ } else {
+ return TypeConversionUtil.isAssignable(returnType, returnType1) ? moreSpecific : -moreSpecific;
+ }
+ }
+ if (returnType1 instanceof PsiPrimitiveType) {
+ return typeKind == TypeKind.PRIMITIVE ? 1 : -1;
}
- }
- if (returnType1 instanceof PsiPrimitiveType) {
- return 1;
}
- final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(returnType);
+ final PsiClassType.ClassResolveResult r = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType));
final PsiClass rClass = r.getElement();
- final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(returnType1);
+ final PsiClassType.ClassResolveResult r1 = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(returnType1));
final PsiClass rClass1 = r1.getElement();
if (rClass != null && rClass1 != null) {
if (rClass == rClass1) {
@@ -728,6 +744,28 @@ public class LambdaUtil {
return 0;
}
+ private static TypeKind areLambdaReturnExpressionsPrimitive(PsiLambdaExpressionType lambdaType) {
+ final List<PsiExpression> returnExpressions = getReturnExpressions(lambdaType.getExpression());
+ TypeKind typeKind = TypeKind.NONE_DETERMINED;
+ for (PsiExpression expression : returnExpressions) {
+ final PsiType returnExprType = expression.getType();
+ if (returnExprType instanceof PsiPrimitiveType) {
+ if (typeKind == TypeKind.REFERENCE) {
+ typeKind = TypeKind.NONE_DETERMINED;
+ break;
+ }
+ typeKind = TypeKind.PRIMITIVE;
+ } else {
+ if (typeKind == TypeKind.PRIMITIVE) {
+ typeKind = TypeKind.NONE_DETERMINED;
+ break;
+ }
+ typeKind = TypeKind.REFERENCE;
+ }
+ }
+ return typeKind;
+ }
+
@Nullable
private static PsiType getReturnType(int functionalTypeIdx, CandidateInfo method) {
final PsiParameter[] methodParameters = ((PsiMethod)method.getElement()).getParameterList().getParameters();
@@ -744,7 +782,7 @@ public class LambdaUtil {
if (owner instanceof PsiModifierList) {
final PsiElement parent = ((PsiModifierList)owner).getParent();
if (parent instanceof PsiClass) {
- return LambdaHighlightingUtil.checkInterfaceFunctional((PsiClass)parent);
+ return LambdaHighlightingUtil.checkInterfaceFunctional((PsiClass)parent, ((PsiClass)parent).getName() + " is not a functional interface");
}
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiAnnotation.java b/java/java-psi-api/src/com/intellij/psi/PsiAnnotation.java
index dd80c5a0bb12..d2c9c77f6d2e 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiAnnotation.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiAnnotation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -42,6 +42,18 @@ public interface PsiAnnotation extends PsiAnnotationMemberValue, PsiMetaOwner {
@NonNls String DEFAULT_REFERENCED_METHOD_NAME = "value";
/**
+ * Kinds of element to which an annotation type is applicable (see {@link java.lang.annotation.ElementType}).
+ */
+ enum TargetType {
+ // see java.lang.annotation.ElementType
+ TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_USE, TYPE_PARAMETER,
+ // auxiliary value, used when it's impossible to determine annotation's targets
+ UNKNOWN;
+
+ public static final TargetType[] EMPTY_ARRAY = {};
+ }
+
+ /**
* Returns the list of parameters for the annotation.
*
* @return the parameter list instance.
@@ -69,8 +81,8 @@ public interface PsiAnnotation extends PsiAnnotationMemberValue, PsiMetaOwner {
/**
* Returns the value of the annotation element with the specified name.
*
- * @param attributeName name of the annotation element for which the value is requested. If it isn't defined in annotation, the default
- * value is returned.
+ * @param attributeName name of the annotation element for which the value is requested. If it isn't defined in annotation,
+ * the default value is returned.
* @return the element value, or null if the annotation does not contain a value for
* the element and the element has no default value.
*/
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiAnnotationOwner.java b/java/java-psi-api/src/com/intellij/psi/PsiAnnotationOwner.java
index 086b28c5b959..fc66868cac80 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiAnnotationOwner.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiAnnotationOwner.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -31,16 +31,15 @@ public interface PsiAnnotationOwner {
@NotNull
PsiAnnotation[] getAnnotations();
-
/**
- * @return the list of annotations which are applicable to this owner.
- * E.g. Type annotations on method belong to its type element, not the method.
+ * @return the list of annotations which are applicable to this owner
+ * (e.g. type annotations on method belong to its type element, not the method).
*/
@NotNull
PsiAnnotation[] getApplicableAnnotations();
/**
- * Searches the modifier list for an annotation with the specified fully qualified name
+ * Searches the owner for an annotation with the specified fully qualified name
* and returns one if it is found.
*
* @param qualifiedName the fully qualified name of the annotation to find.
@@ -50,7 +49,7 @@ public interface PsiAnnotationOwner {
PsiAnnotation findAnnotation(@NotNull @NonNls String qualifiedName);
/**
- * Add a new annotation to this modifier list. The annotation class name will be shortened. No attributes will be defined.
+ * Adds a new annotation to this owner. The annotation class name will be shortened. No attributes will be defined.
*
* @param qualifiedName qualifiedName
* @return newly added annotation
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java
index 1c6ed36d97bd..39d4dac9494a 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiArrayType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -36,14 +36,14 @@ public class PsiArrayType extends PsiType {
this(componentType, PsiAnnotation.EMPTY_ARRAY);
}
- public PsiArrayType(@NotNull PsiType componentType, PsiAnnotation[] annotations) {
+ public PsiArrayType(@NotNull PsiType componentType, @NotNull PsiAnnotation[] annotations) {
super(annotations);
myComponentType = componentType;
}
@Override
public String getPresentableText() {
- return StringUtil.joinOrNull(myComponentType.getPresentableText(), "[]");
+ return StringUtil.joinOrNull(myComponentType.getPresentableText(), getAnnotationsTextPrefix(false, true, true), "[]");
}
@Override
@@ -53,7 +53,7 @@ public class PsiArrayType extends PsiType {
@Override
public String getInternalCanonicalText() {
- return StringUtil.joinOrNull(myComponentType.getInternalCanonicalText(), "[]");
+ return StringUtil.joinOrNull(myComponentType.getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "[]");
}
@Override
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java
index 649f355502ca..5a85ba65fdff 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -39,11 +39,13 @@ public abstract class PsiClassType extends PsiType {
return new PsiClassType[count];
}
};
+
protected final LanguageLevel myLanguageLevel;
protected PsiClassType(LanguageLevel languageLevel) {
this(languageLevel, PsiAnnotation.EMPTY_ARRAY);
}
+
protected PsiClassType(LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations) {
super(annotations);
myLanguageLevel = languageLevel;
@@ -69,7 +71,8 @@ public abstract class PsiClassType extends PsiType {
*
* @return the array of type arguments, or an empty array if the type does not point to a generic class or interface.
*/
- @NotNull public abstract PsiType[] getParameters();
+ @NotNull
+ public abstract PsiType[] getParameters();
public int getParameterCount() {
return getParameters().length;
@@ -78,8 +81,7 @@ public abstract class PsiClassType extends PsiType {
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof PsiClassType)) return false;
- PsiClassType otherClassType = (PsiClassType) obj;
- //if (!isValid() || !otherClassType.isValid()) return false;
+ PsiClassType otherClassType = (PsiClassType)obj;
String className = getClassName();
String otherClassName = otherClassType.getClassName();
@@ -158,20 +160,20 @@ public abstract class PsiClassType extends PsiType {
@Override
@NotNull
public PsiType[] getSuperTypes() {
- final ClassResolveResult resolveResult = resolveGenerics();
- final PsiClass aClass = resolveResult.getElement();
+ ClassResolveResult resolveResult = resolveGenerics();
+ PsiClass aClass = resolveResult.getElement();
if (aClass == null) return EMPTY_ARRAY;
- final PsiClassType[] superTypes = aClass.getSuperTypes();
- final PsiType[] subtitutionResults = new PsiType[superTypes.length];
+ PsiClassType[] superTypes = aClass.getSuperTypes();
+ PsiType[] substitutionResults = new PsiType[superTypes.length];
for (int i = 0; i < superTypes.length; i++) {
- subtitutionResults[i] = resolveResult.getSubstitutor().substitute(superTypes[i]);
+ substitutionResults[i] = resolveResult.getSubstitutor().substitute(superTypes[i]);
}
- return subtitutionResults;
+ return substitutionResults;
}
/**
- * Checks whether the specified resolve result representss a raw type. <br>
+ * Checks whether the specified resolve result represents a raw type. <br>
* Raw type is a class type for a class <i>with type parameters</i> which does not assign
* any value to them. If a class does not have any type parameters, it cannot generate any raw type.
*/
@@ -196,14 +198,16 @@ public abstract class PsiClassType extends PsiType {
*
* @return the resolve result instance.
*/
- @NotNull public abstract ClassResolveResult resolveGenerics();
+ @NotNull
+ public abstract ClassResolveResult resolveGenerics();
/**
* Returns the raw type (with no values assigned to type parameters) corresponding to this type.
*
* @return the raw type instance.
*/
- @NotNull public abstract PsiClassType rawType();
+ @NotNull
+ public abstract PsiClassType rawType();
/**
* Overrides {@link com.intellij.psi.PsiType#getResolveScope()} to narrow specify @NotNull.
@@ -223,6 +227,7 @@ public abstract class PsiClassType extends PsiType {
/**
* Functional style setter preserving original type's language level
+ *
* @param languageLevel level to obtain class type with
* @return type with requested language level
*/
@@ -248,17 +253,17 @@ public abstract class PsiClassType extends PsiType {
}
@Override
- public boolean isValidResult(){
+ public boolean isValidResult() {
return false;
}
@Override
- public boolean isAccessible(){
+ public boolean isAccessible() {
return false;
}
@Override
- public boolean isStaticsScopeCorrect(){
+ public boolean isStaticsScopeCorrect() {
return false;
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiElementFactory.java b/java/java-psi-api/src/com/intellij/psi/PsiElementFactory.java
index 27eeb0a2663f..3838dc1ef1ff 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiElementFactory.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiElementFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -43,7 +43,7 @@ public interface PsiElementFactory extends PsiJavaParserFacade, JVMElementFactor
return ServiceManager.getService(project, PsiElementFactory.class);
}
}
-
+
/**
* Creates an empty class with the specified name.
*
@@ -164,12 +164,21 @@ public interface PsiElementFactory extends PsiJavaParserFacade, JVMElementFactor
*/
@NotNull PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor);
- /*
- additional languageLevel parameter to memorize language level for allowing/prohibiting boxing/unboxing
+ /**
+ * Creates a class type for the specified class, using the specified substitutor
+ * to replace generic type parameters on the class.
+ *
+ * @param resolve the class for which the class type is created.
+ * @param substitutor the substitutor to use.
+ * @param languageLevel to memorize language level for allowing/prohibiting boxing/unboxing.
+ * @return the class type instance.
*/
- @NotNull PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @NotNull LanguageLevel languageLevel);
+ @NotNull PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @Nullable LanguageLevel languageLevel);
- @NotNull PsiClassType createType(@NotNull PsiClass resolve, @NotNull PsiSubstitutor substitutor, @NotNull LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations);
+ @NotNull PsiClassType createType(@NotNull PsiClass resolve,
+ @NotNull PsiSubstitutor substitutor,
+ @Nullable LanguageLevel languageLevel,
+ @NotNull PsiAnnotation[] annotations);
/**
* Creates a class type for the specified reference pointing to a class.
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java
index f295375f9403..498137e87709 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiEllipsisType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -18,7 +18,6 @@ package com.intellij.psi;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.NotNull;
-
/**
* Represents the type of a variable arguments array passed as a method parameter.
*
@@ -36,7 +35,7 @@ public class PsiEllipsisType extends PsiArrayType {
@Override
public String getPresentableText() {
- return StringUtil.joinOrNull(getComponentType().getPresentableText(), "...");
+ return StringUtil.joinOrNull(getComponentType().getPresentableText(), getAnnotationsTextPrefix(false, true, true), "...");
}
@Override
@@ -46,13 +45,13 @@ public class PsiEllipsisType extends PsiArrayType {
@Override
public String getInternalCanonicalText() {
- return StringUtil.joinOrNull(getComponentType().getInternalCanonicalText(), "...");
+ return StringUtil.joinOrNull(getComponentType().getInternalCanonicalText(), getAnnotationsTextPrefix(true, true, true), "...");
}
@Override
public boolean equalsToText(String text) {
- return text.endsWith("...") && getComponentType().equalsToText(text.substring(0, text.length() - 3))
- || super.equalsToText(text);
+ return text.endsWith("...") && getComponentType().equalsToText(text.substring(0, text.length() - 3)) ||
+ super.equalsToText(text);
}
/**
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
index 8c13cd7582c6..8bc973444dfd 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiIntersectionType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -169,10 +169,11 @@ public class PsiIntersectionType extends PsiType {
@Override
public String toString() {
- String s = "PsiIntersectionType: ";
- for (PsiType conjunct : myConjuncts) {
- s += conjunct.getPresentableText() +", ";
+ StringBuilder sb = new StringBuilder("PsiIntersectionType: ");
+ for (int i = 0; i < myConjuncts.length; i++) {
+ if (i > 0) sb.append(", ");
+ sb.append(myConjuncts[i].getPresentableText());
}
- return s;
+ return sb.toString();
}
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
index b30a7cc7a09f..b2f80104449c 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -40,7 +40,7 @@ public interface PsiJavaCodeReferenceElement extends PsiJavaReference, PsiQualif
* Returns the element representing the name of the referenced element.
*
* @return the element, or null if the reference element is not physical (for example,
- * exists in compiled code).
+ * exists in compiled code).
*/
@Nullable
PsiElement getReferenceNameElement();
@@ -74,5 +74,4 @@ public interface PsiJavaCodeReferenceElement extends PsiJavaReference, PsiQualif
* @return the qualified text of the reference.
*/
String getQualifiedName();
-
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index 1d0b2d750304..b051604ff656 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -191,6 +191,7 @@ public class PsiMethodReferenceUtil {
}
public static boolean isReceiverType(PsiType receiverType, @Nullable PsiClass containingClass, PsiSubstitutor psiSubstitutor) {
+ boolean arrayType = receiverType instanceof PsiArrayType;
if (containingClass != null) {
receiverType = getExpandedType(receiverType, containingClass);
}
@@ -198,7 +199,8 @@ public class PsiMethodReferenceUtil {
final PsiClass receiverClass = resolveResult.getElement();
if (receiverClass != null && isReceiverType(receiverClass, containingClass)) {
LOG.assertTrue(containingClass != null);
- return resolveResult.getSubstitutor().equals(psiSubstitutor) ||
+ return arrayType ||
+ resolveResult.getSubstitutor().equals(psiSubstitutor) ||
emptyOrRaw(containingClass, psiSubstitutor) ||
emptyOrRaw(receiverClass, resolveResult.getSubstitutor());
}
@@ -260,6 +262,9 @@ public class PsiMethodReferenceUtil {
for (int i = 0; i < min; i++) {
final PsiType type1 = GenericsUtil.eliminateWildcards(psiSubstitutor.substitute(signatureParameterTypes1[offset + i]));
if (isVarargs && i == min - 1) {
+ if (!(signatureParameterTypes2[i] instanceof PsiArrayType)) {
+ return false;
+ }
if (!TypeConversionUtil.isAssignable(((PsiArrayType)signatureParameterTypes2[i]).getComponentType(), type1) &&
!TypeConversionUtil.isAssignable(signatureParameterTypes2[i], type1)) {
return false;
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiNewExpression.java b/java/java-psi-api/src/com/intellij/psi/PsiNewExpression.java
index bebd2703a054..d8fa9a116251 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiNewExpression.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiNewExpression.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -37,7 +37,7 @@ public interface PsiNewExpression extends PsiCallExpression, PsiConstructorCall
* an array creation expression.
*
* @return the array of expressions for the dimensions, or an empty array if the
- * <code>new</code> expression is not an array creation expression.
+ * <code>new</code> expression is not an array creation expression.
*/
@NotNull
PsiExpression[] getArrayDimensions();
@@ -47,7 +47,7 @@ public interface PsiNewExpression extends PsiCallExpression, PsiConstructorCall
* an array creation expression.
*
* @return the array initializer expression, or null if the <code>new</code>
- * expression is not an array creation expression or has no initializer.
+ * expression is not an array creation expression or has no initializer.
*/
@Nullable
PsiArrayInitializerExpression getArrayInitializer();
@@ -63,8 +63,7 @@ public interface PsiNewExpression extends PsiCallExpression, PsiConstructorCall
/**
* Returns the anonymous class created by the <code>new</code> expression.
*
- * @return the anonymous class, or null if the expression does not create an
- * anonymous class.
+ * @return the anonymous class, or null if the expression does not create an anonymous class.
*/
@Nullable
PsiAnonymousClass getAnonymousClass();
@@ -75,5 +74,16 @@ public interface PsiNewExpression extends PsiCallExpression, PsiConstructorCall
*
* @return class reference, or null if the expression is incomplete.
*/
- @Nullable PsiJavaCodeReferenceElement getClassOrAnonymousClassReference();
+ @Nullable
+ PsiJavaCodeReferenceElement getClassOrAnonymousClassReference();
+
+ /**
+ * For type-annotated array creation expressions returns subtype of getType(),
+ * to which an annotation belongs.
+ *
+ * @param annotation annotation to find the type for.
+ * @return annotated subtype or null, if annotation is incorrectly placed.
+ */
+ @Nullable
+ PsiType getOwner(@NotNull PsiAnnotation annotation);
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
index acbbfdfdb014..0a38c643799c 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiPrimitiveType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -53,7 +53,7 @@ public class PsiPrimitiveType extends PsiType {
@Override
public String getPresentableText() {
- return myName;
+ return getAnnotationsTextPrefix(false, false, true) + myName;
}
@Override
@@ -63,7 +63,7 @@ public class PsiPrimitiveType extends PsiType {
@Override
public String getInternalCanonicalText() {
- return getAnnotationsTextPrefix() + getCanonicalText();
+ return getAnnotationsTextPrefix(true, false, true) + myName;
}
/**
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiType.java b/java/java-psi-api/src/com/intellij/psi/PsiType.java
index 5ed21bd5fdd0..cc78466a7e4a 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiType.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -17,8 +17,6 @@ package com.intellij.psi;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.Function;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +39,7 @@ public abstract class PsiType implements PsiAnnotationOwner {
public static final PsiType[] EMPTY_ARRAY = new PsiType[0];
private final PsiAnnotation[] myAnnotations;
+
protected PsiType(@NotNull PsiAnnotation[] annotations) {
myAnnotations = annotations;
}
@@ -52,22 +51,31 @@ public abstract class PsiType implements PsiAnnotationOwner {
public PsiArrayType createArrayType() {
return new PsiArrayType(this);
}
+
/**
* Creates array type with this type as a component.
*/
@NotNull
public PsiArrayType createArrayType(PsiAnnotation... annotations) {
- return new PsiArrayType(this,annotations);
+ return new PsiArrayType(this, annotations);
}
/**
- * @return text of this type that can be presented to user.
+ * @return text of the type that can be presented to a user (non-qualified references, with annotations).
*/
+ @NonNls
public abstract String getPresentableText();
+ /**
+ * @return text of the type (fully-qualified references, no annotations).
+ */
@NonNls
public abstract String getCanonicalText();
+ /**
+ * @return text of the type (fully-qualified references, with annotations).
+ */
+ @NonNls
public abstract String getInternalCanonicalText();
/**
@@ -109,7 +117,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
*/
@NotNull
public static PsiClassType getJavaLangObject(@NotNull PsiManager manager, @NotNull GlobalSearchScope resolveScope) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+ return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, resolveScope);
}
/**
@@ -120,7 +129,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
* @return the class instance.
*/
public static PsiClassType getJavaLangClass(PsiManager manager, GlobalSearchScope resolveScope) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_CLASS, resolveScope);
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+ return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_CLASS, resolveScope);
}
/**
@@ -131,7 +141,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
* @return the class instance.
*/
public static PsiClassType getJavaLangThrowable(PsiManager manager, GlobalSearchScope resolveScope) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE, resolveScope);
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+ return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE, resolveScope);
}
/**
@@ -143,7 +154,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
*/
@NotNull
public static PsiClassType getJavaLangString(PsiManager manager, GlobalSearchScope resolveScope) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, resolveScope);
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+ return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, resolveScope);
}
/**
@@ -154,7 +166,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
* @return the class instance.
*/
public static PsiClassType getJavaLangError(PsiManager manager, GlobalSearchScope resolveScope) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_ERROR, resolveScope);
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+ return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_ERROR, resolveScope);
}
/**
@@ -165,7 +178,8 @@ public abstract class PsiType implements PsiAnnotationOwner {
* @return the class instance.
*/
public static PsiClassType getJavaLangRuntimeException(PsiManager manager, GlobalSearchScope resolveScope) {
- return JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createTypeByFQClassName(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, resolveScope);
+ PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+ return factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_RUNTIME_EXCEPTION, resolveScope);
}
/**
@@ -195,7 +209,7 @@ public abstract class PsiType implements PsiAnnotationOwner {
* Returns the innermost component type for an array type.
*
* @return the innermost (non-array) component of the type, or <code>this</code> if the type is not
- * an array type.
+ * an array type.
*/
@NotNull
public final PsiType getDeepComponentType() {
@@ -214,11 +228,6 @@ public abstract class PsiType implements PsiAnnotationOwner {
@Nullable
public abstract GlobalSearchScope getResolveScope();
- public String toString() {
- //noinspection HardCodedStringLiteral
- return "PsiType:" + getPresentableText();
- }
-
/**
* Returns the list of superclass types for a class type.
*
@@ -250,14 +259,36 @@ public abstract class PsiType implements PsiAnnotationOwner {
return getAnnotations();
}
+ /** @deprecated use {@link #getAnnotationsTextPrefix(boolean, boolean, boolean)} (to remove in IDEA 13) */
+ @SuppressWarnings("UnusedDeclaration")
protected String getAnnotationsTextPrefix() {
+ return getAnnotationsTextPrefix(false, false, true);
+ }
+
+ @NotNull
+ protected String getAnnotationsTextPrefix(boolean qualified, boolean leadingSpace, boolean trailingSpace) {
PsiAnnotation[] annotations = getAnnotations();
- return StringUtil.join(annotations, new Function<PsiAnnotation, String>() {
- @Override
- public String fun(PsiAnnotation annotation) {
- return "@"+annotation.getQualifiedName();
+ if (annotations.length == 0) return "";
+
+ StringBuilder sb = new StringBuilder();
+ if (leadingSpace) sb.append(' ');
+ for (int i = 0; i < annotations.length; i++) {
+ if (i > 0) sb.append(' ');
+ PsiAnnotation annotation = annotations[i];
+ if (qualified) {
+ sb.append('@').append(annotation.getQualifiedName()).append(annotation.getParameterList().getText());
+ }
+ else {
+ sb.append(annotation.getText());
}
- }, " ") + (annotations.length == 0 ? "" : " ");
+ }
+ if (trailingSpace) sb.append(' ');
+ return sb.toString();
}
+ @Override
+ public String toString() {
+ //noinspection HardCodedStringLiteral
+ return "PsiType:" + getPresentableText();
+ }
}
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiTypeElement.java b/java/java-psi-api/src/com/intellij/psi/PsiTypeElement.java
index 57e5381f6550..64a7b8066820 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiTypeElement.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiTypeElement.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -53,6 +53,7 @@ public interface PsiTypeElement extends PsiElement,PsiAnnotationOwner {
@Nullable
PsiJavaCodeReferenceElement getInnermostComponentReferenceElement();
+ /** @deprecated equals to getType() (to remove in IDEA 13) */
PsiAnnotationOwner getOwner(PsiAnnotation annotation);
PsiType getTypeNoResolve(@NotNull PsiElement context);
diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
index cac0f3bc2c89..01726de99d24 100644
--- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
+++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java
@@ -151,6 +151,23 @@ public class MethodCandidateInfo extends CandidateInfo{
: PsiExpression.EMPTY_ARRAY);
}
+ public PsiSubstitutor inferSubstitutorFromArgs(final ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) {
+ if (myTypeArguments == null) {
+ return inferTypeArguments(policy, arguments);
+ }
+ else {
+ PsiSubstitutor incompleteSubstitutor = super.getSubstitutor();
+ PsiMethod method = getElement();
+ if (method != null) {
+ PsiTypeParameter[] typeParams = method.getTypeParameters();
+ for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) {
+ incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]);
+ }
+ }
+ return incompleteSubstitutor;
+ }
+ }
+
public PsiSubstitutor inferTypeArguments(final ParameterTypeInferencePolicy policy, final PsiExpression[] arguments) {
Map<PsiElement, Pair<PsiMethod, PsiSubstitutor>> map = CURRENT_CANDIDATE.get();
if (map == null) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index bba6f97400b8..49fbfec70d4c 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -722,9 +722,14 @@ public final class PsiUtil extends PsiUtilCore {
@PsiModifier.ModifierConstant
public static String getMaximumModifierForMember(final PsiClass aClass) {
+ return getMaximumModifierForMember(aClass, true);
+ }
+
+ @PsiModifier.ModifierConstant
+ public static String getMaximumModifierForMember(final PsiClass aClass, boolean allowPublicAbstract) {
String modifier = PsiModifier.PUBLIC;
- if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) && !aClass.isEnum()) {
+ if (!allowPublicAbstract && aClass.hasModifierProperty(PsiModifier.ABSTRACT) && !aClass.isEnum()) {
modifier = PsiModifier.PROTECTED;
}
else if (aClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
index 09ef657b4c4a..672a01334f47 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypeConversionUtil.java
@@ -708,7 +708,7 @@ public class TypeConversionUtil {
}
if (left instanceof PsiCapturedWildcardType) {
- return left.equals(right) || isAssignable(((PsiCapturedWildcardType)left).getLowerBound(), right, false);
+ return left.equals(right) || isAssignable(((PsiCapturedWildcardType)left).getLowerBound(), right, allowUncheckedConversion);
}
if (right instanceof PsiCapturedWildcardType) {
return isAssignable(left, ((PsiCapturedWildcardType)right).getUpperBound(), allowUncheckedConversion);
@@ -896,7 +896,9 @@ public class TypeConversionUtil {
PsiSubstitutor leftSubstitutor = leftResult.getSubstitutor();
if (!leftClass.getManager().areElementsEquivalent(leftClass, rightClass)) {
- if (!allowUncheckedConversion && PsiUtil.isRawSubstitutor(leftClass, leftSubstitutor) && !rightClass.hasTypeParameters() && !(rightClass instanceof PsiTypeParameter)) return false;
+ if (!allowUncheckedConversion && PsiUtil.isRawSubstitutor(leftClass, leftSubstitutor) && !rightClass.hasTypeParameters() && !(rightClass instanceof PsiTypeParameter)) {
+ return false;
+ }
rightSubstitutor = getSuperClassSubstitutor(leftClass, rightClass, rightSubstitutor);
rightClass = leftClass;
}