summaryrefslogtreecommitdiff
path: root/java/java-psi-api/src
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-08-15 14:06:37 -0700
committerTor Norbye <tnorbye@google.com>2013-08-15 14:06:37 -0700
commita3c36999a717e0d9923378ca5e0ae1160118c1e6 (patch)
treeeda7fde5565d08649c0f5952e957a5ff4b2070d5 /java/java-psi-api/src
parentd1129abbe4dc0ce9bbad9118a35a85dbebc8758f (diff)
downloadidea-a3c36999a717e0d9923378ca5e0ae1160118c1e6.tar.gz
Snapshot 13baaa319cd568c4e19b9232b24f2002f2631688 from master branch of git://git.jetbrains.org/idea/community.git
Change-Id: I2ede7fef748e781ed425346a4e03e721bf4d2610
Diffstat (limited to 'java/java-psi-api/src')
-rw-r--r--java/java-psi-api/src/com/intellij/psi/GenericsUtil.java52
-rw-r--r--java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java4
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java36
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java37
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/JavaMatchers.java44
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java2
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PropertyMemberType.java24
-rw-r--r--java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java26
-rw-r--r--java/java-psi-api/src/com/intellij/util/VisibilityUtil.java6
9 files changed, 218 insertions, 13 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 ff3543a37f16..c09660c4af08 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -239,7 +239,16 @@ public class GenericsUtil {
supers.add(classToAdd);
}
- public static boolean isTypeArgumentsApplicable(PsiTypeParameter[] typeParams, PsiSubstitutor substitutor, final PsiElement context) {
+ public static boolean isTypeArgumentsApplicable(final PsiTypeParameter[] typeParams,
+ final PsiSubstitutor substitutor,
+ final PsiElement context) {
+ return isTypeArgumentsApplicable(typeParams, substitutor, context, true);
+ }
+
+ public static boolean isTypeArgumentsApplicable(final PsiTypeParameter[] typeParams,
+ final PsiSubstitutor substitutor,
+ final PsiElement context,
+ final boolean allowUncheckedConversion) {
nextTypeParam:
for (PsiTypeParameter typeParameter : typeParams) {
PsiType substituted = substitutor.substitute(typeParameter);
@@ -249,16 +258,49 @@ public class GenericsUtil {
PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes();
for (PsiClassType type : extendsTypes) {
PsiType extendsType = substitutor.substitute(type);
- if (extendsType.isAssignableFrom(substituted)) {
- continue nextTypeParam;
+ if (substituted instanceof PsiWildcardType) {
+ if (((PsiWildcardType)substituted).isSuper()) {
+ continue;
+ }
+ final PsiType extendsBound = ((PsiWildcardType)substituted).getExtendsBound();
+ if (TypeConversionUtil.erasure(extendsType).equals(TypeConversionUtil.erasure(extendsBound))) {
+ if (extendsBound instanceof PsiClassType) {
+ if (acceptExtendsBound((PsiClassType)extendsBound, 0)) continue;
+ } else if (extendsBound instanceof PsiIntersectionType) {
+ for (PsiType psiType : ((PsiIntersectionType)extendsBound).getConjuncts()) {
+ if (psiType instanceof PsiClassType) {
+ if (acceptExtendsBound((PsiClassType)psiType, 0)) continue nextTypeParam;
+ }
+ }
+ }
+ }
+ }
+ if (!TypeConversionUtil.isAssignable(extendsType, substituted, allowUncheckedConversion)) {
+ return false;
}
}
- if (extendsTypes.length > 0) return false;
}
-
return true;
}
+ private static boolean acceptExtendsBound(PsiClassType extendsBound, int depth) {
+ PsiType[] parameters = extendsBound.getParameters();
+ if (parameters.length == 1) {
+ PsiType argType = parameters[0];
+ if (argType instanceof PsiCapturedWildcardType && depth == 0) {
+ argType = ((PsiCapturedWildcardType)argType).getWildcard();
+ }
+ if (argType instanceof PsiWildcardType) {
+ if (!((PsiWildcardType)argType).isBounded()) return true;
+ final PsiType bound = ((PsiWildcardType)argType).getExtendsBound();
+ if (bound instanceof PsiClassType && TypeConversionUtil.erasure(bound).equals(TypeConversionUtil.erasure(extendsBound))) {
+ return acceptExtendsBound((PsiClassType)bound, depth + 1);
+ }
+ }
+ }
+ return false;
+ }
+
public static boolean isFromExternalTypeLanguage(@NotNull PsiType type) {
String internalCanonicalText = type.getInternalCanonicalText();
return internalCanonicalText != null && internalCanonicalText.equals(type.getCanonicalText());
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 94f4cd30ffd0..299575ef5632 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
@@ -94,6 +94,10 @@ public class MethodCandidateInfo extends CandidateInfo{
return myApplicabilityLevel;
}
+ public PsiSubstitutor getSiteSubstitutor() {
+ return super.getSubstitutor();
+ }
+
@Override
public PsiSubstitutor getSubstitutor() {
if (myCalcedSubstitutor == null) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java b/java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java
new file mode 100644
index 000000000000..4a370cd914b3
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+public class EnclosingLoopMatcherExpression implements PsiMatcherExpression {
+ public static final PsiMatcherExpression INSTANCE = new EnclosingLoopMatcherExpression();
+
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element instanceof PsiForStatement) return Boolean.TRUE;
+ if (element instanceof PsiForeachStatement) return Boolean.TRUE;
+ if (element instanceof PsiWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiDoWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiMethod || element instanceof PsiClassInitializer) return null;
+ return Boolean.FALSE;
+ }
+} \ No newline at end of file
diff --git a/java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java b/java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java
new file mode 100644
index 000000000000..b40ce6882bb1
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+public class EnclosingLoopOrSwitchMatcherExpression implements PsiMatcherExpression {
+ public static final PsiMatcherExpression INSTANCE = new EnclosingLoopOrSwitchMatcherExpression();
+
+ @Override
+ public Boolean match(PsiElement element) {
+ if (element instanceof PsiForStatement) return Boolean.TRUE;
+ if (element instanceof PsiForeachStatement) return Boolean.TRUE;
+ if (element instanceof PsiWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiDoWhileStatement) return Boolean.TRUE;
+ if (element instanceof PsiSwitchStatement) return Boolean.TRUE;
+ if (element instanceof PsiMethod || element instanceof PsiClassInitializer) return null;
+ return Boolean.FALSE;
+ }
+} \ No newline at end of file
diff --git a/java/java-psi-api/src/com/intellij/psi/util/JavaMatchers.java b/java/java-psi-api/src/com/intellij/psi/util/JavaMatchers.java
new file mode 100644
index 000000000000..4378141bfc5d
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/psi/util/JavaMatchers.java
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ * 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.util;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiModifierListOwner;
+
+public class JavaMatchers {
+ public static PsiMatcherExpression isConstructor(final boolean shouldBe) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ return element instanceof PsiMethod && ((PsiMethod)element).isConstructor() == shouldBe;
+ }
+ };
+ }
+
+ public static PsiMatcherExpression hasModifier(@PsiModifier.ModifierConstant final String modifier, final boolean shouldHave) {
+ return new PsiMatcherExpression() {
+ @Override
+ public Boolean match(PsiElement element) {
+ PsiModifierListOwner owner = element instanceof PsiModifierListOwner ? (PsiModifierListOwner) element : null;
+
+ if (owner != null && owner.hasModifierProperty(modifier) == shouldHave) return Boolean.TRUE;
+ return Boolean.FALSE;
+ }
+ };
+ }
+}
diff --git a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java
index 077dc8019fa3..b514fa2349c4 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/MethodSignatureUtil.java
@@ -58,7 +58,7 @@ public class MethodSignatureUtil {
}
};
- private static boolean areErasedParametersEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
+ public static boolean areErasedParametersEqual(@NotNull MethodSignature method1, @NotNull MethodSignature method2) {
PsiType[] erased1 = method1 instanceof MethodSignatureBase
? ((MethodSignatureBase)method1).getErasedParameterTypes() : calcErasedParameterTypes(method1);
PsiType[] erased2 = method2 instanceof MethodSignatureBase
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PropertyMemberType.java b/java/java-psi-api/src/com/intellij/psi/util/PropertyMemberType.java
new file mode 100644
index 000000000000..90bdec5caf44
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/psi/util/PropertyMemberType.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2009 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.util;
+
+/**
+ * @author Gregory.Shrago
+*/
+public enum PropertyMemberType {
+ FIELD, GETTER, SETTER
+}
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 66cb12fad3ed..642d8559e712 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
@@ -92,7 +92,11 @@ public final class PsiUtil extends PsiUtilCore {
}
public static boolean isAccessible(@NotNull PsiMember member, @NotNull PsiElement place, @Nullable PsiClass accessObjectClass) {
- return JavaPsiFacade.getInstance(place.getProject()).getResolveHelper().isAccessible(member, place, accessObjectClass);
+ return isAccessible(place.getProject(), member, place, accessObjectClass);
+ }
+ public static boolean isAccessible(@NotNull Project project, @NotNull PsiMember member,
+ @NotNull PsiElement place, @Nullable PsiClass accessObjectClass) {
+ return JavaPsiFacade.getInstance(project).getResolveHelper().isAccessible(member, place, accessObjectClass);
}
@NotNull
@@ -462,8 +466,20 @@ public final class PsiUtil extends PsiUtilCore {
}
@MethodCandidateInfo.ApplicabilityLevelConstant
- public static int getApplicabilityLevel(@NotNull final PsiMethod method, @NotNull final PsiSubstitutor substitutorForMethod, @NotNull final PsiType[] args,
- @NotNull final LanguageLevel languageLevel) {
+ public static int getApplicabilityLevel(@NotNull final PsiMethod method,
+ @NotNull final PsiSubstitutor substitutorForMethod,
+ @NotNull final PsiType[] args,
+ @NotNull final LanguageLevel languageLevel) {
+ return getApplicabilityLevel(method, substitutorForMethod, args, languageLevel, true, true);
+ }
+
+ @MethodCandidateInfo.ApplicabilityLevelConstant
+ public static int getApplicabilityLevel(@NotNull final PsiMethod method,
+ @NotNull final PsiSubstitutor substitutorForMethod,
+ @NotNull final PsiType[] args,
+ @NotNull final LanguageLevel languageLevel,
+ final boolean allowUncheckedConversion,
+ final boolean checkVarargs) {
final PsiParameter[] parms = method.getParameterList().getParameters();
if (args.length < parms.length - 1) return ApplicabilityLevel.NOT_APPLICABLE;
@@ -475,7 +491,7 @@ public final class PsiUtil extends PsiUtilCore {
PsiType parmType = getParameterType(parms[parms.length - 1], languageLevel, substitutorForMethod);
PsiType argType = args[args.length - 1];
if (argType == null) return ApplicabilityLevel.NOT_APPLICABLE;
- if (TypeConversionUtil.isAssignable(parmType, argType)) return ApplicabilityLevel.FIXED_ARITY;
+ if (TypeConversionUtil.isAssignable(parmType, argType, allowUncheckedConversion)) return ApplicabilityLevel.FIXED_ARITY;
if (isRaw) {
final PsiType erasedParamType = TypeConversionUtil.erasure(parmType);
@@ -487,7 +503,7 @@ public final class PsiUtil extends PsiUtilCore {
}
}
- if (method.isVarArgs() && languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0) {
+ if (checkVarargs && method.isVarArgs() && languageLevel.compareTo(LanguageLevel.JDK_1_5) >= 0) {
if (args.length < parms.length) return ApplicabilityLevel.VARARGS;
PsiParameter lastParameter = parms[parms.length - 1];
if (!lastParameter.isVarArgs()) return ApplicabilityLevel.NOT_APPLICABLE;
diff --git a/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java b/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
index 7ee8b1d296e7..e1f30930c75b 100644
--- a/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
+++ b/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
@@ -24,6 +24,7 @@
*/
package com.intellij.util;
+import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
@@ -69,8 +70,9 @@ public class VisibilityUtil {
@PsiModifier.ModifierConstant
public static String getPossibleVisibility(final PsiMember psiMethod, final PsiElement place) {
- if (PsiUtil.isAccessible(psiMethod, place, null)) return getVisibilityModifier(psiMethod.getModifierList());
- if (JavaPsiFacade.getInstance(psiMethod.getProject()).arePackagesTheSame(psiMethod, place)) {
+ Project project = psiMethod.getProject();
+ if (PsiUtil.isAccessible(project, psiMethod, place, null)) return getVisibilityModifier(psiMethod.getModifierList());
+ if (JavaPsiFacade.getInstance(project).arePackagesTheSame(psiMethod, place)) {
return PsiModifier.PACKAGE_LOCAL;
}
if (InheritanceUtil.isInheritorOrSelf(PsiTreeUtil.getParentOfType(place, PsiClass.class),