diff options
author | Tor Norbye <tnorbye@google.com> | 2013-08-15 14:06:37 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-08-15 14:06:37 -0700 |
commit | a3c36999a717e0d9923378ca5e0ae1160118c1e6 (patch) | |
tree | eda7fde5565d08649c0f5952e957a5ff4b2070d5 /java/java-psi-api/src | |
parent | d1129abbe4dc0ce9bbad9118a35a85dbebc8758f (diff) | |
download | idea-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')
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), |