diff options
Diffstat (limited to 'java/java-psi-api')
8 files changed, 133 insertions, 10 deletions
diff --git a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java index c0cd96c20d47..c2c79a9d9d8a 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/AnnotationUtil.java @@ -113,13 +113,21 @@ public class AnnotationUtil { } } if (!skipExternal) { - final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(listOwner.getProject()); + final Project project = listOwner.getProject(); + final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project); for (String annotationName : annotationNames) { final PsiAnnotation annotation = annotationsManager.findExternalAnnotation(listOwner, annotationName); if (annotation != null) { return annotation; } } + final InferredAnnotationsManager inferredAnnotationsManager = InferredAnnotationsManager.getInstance(project); + for (String annotationName : annotationNames) { + final PsiAnnotation annotation = inferredAnnotationsManager.findInferredAnnotation(listOwner, annotationName); + if (annotation != null) { + return annotation; + } + } } return null; } @@ -269,8 +277,12 @@ public class AnnotationUtil { if (modifierList == null) return false; PsiAnnotation annotation = modifierList.findAnnotation(annotationFQN); if (annotation != null) return true; - if (!skipExternal && ExternalAnnotationsManager.getInstance(listOwner.getProject()).findExternalAnnotation(listOwner, annotationFQN) != null) { - return true; + if (!skipExternal) { + final Project project = listOwner.getProject(); + if (ExternalAnnotationsManager.getInstance(project).findExternalAnnotation(listOwner, annotationFQN) != null || + InferredAnnotationsManager.getInstance(project).findInferredAnnotation(listOwner, annotationFQN) != null) { + return true; + } } if (checkHierarchy) { if (listOwner instanceof PsiMethod) { @@ -365,17 +377,31 @@ public class AnnotationUtil { } @NotNull - public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner, boolean inHierarchy, Set<PsiModifierListOwner> visited) { + public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner, + boolean inHierarchy, + Set<PsiModifierListOwner> visited) { + return getAllAnnotations(owner, inHierarchy, visited, true); + } + + @NotNull + public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner, + boolean inHierarchy, + Set<PsiModifierListOwner> visited, boolean withInferred) { final PsiModifierList list = owner.getModifierList(); PsiAnnotation[] annotations = PsiAnnotation.EMPTY_ARRAY; if (list != null) { annotations = list.getAnnotations(); } - final PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner); + final Project project = owner.getProject(); + final PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(project).findExternalAnnotations(owner); if (externalAnnotations != null) { annotations = ArrayUtil.mergeArrays(annotations, externalAnnotations, PsiAnnotation.ARRAY_FACTORY); } + if (withInferred) { + final PsiAnnotation[] inferredAnnotations = InferredAnnotationsManager.getInstance(project).findInferredAnnotations(owner); + annotations = ArrayUtil.mergeArrays(annotations, inferredAnnotations, PsiAnnotation.ARRAY_FACTORY); + } if (inHierarchy) { if (owner instanceof PsiClass) { @@ -435,6 +461,10 @@ public class AnnotationUtil { return PsiTreeUtil.getParentOfType(element, PsiNameValuePair.class, PsiArrayInitializerMemberValue.class) != null; } + public static boolean isInferredAnnotation(@NotNull PsiAnnotation annotation) { + return InferredAnnotationsManager.getInstance(annotation.getProject()).isInferredAnnotation(annotation); + } + @Nullable public static String getStringAttributeValue(@NotNull PsiAnnotation anno, @Nullable final String attributeName) { PsiAnnotationMemberValue attrValue = anno.findAttributeValue(attributeName); diff --git a/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java b/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java new file mode 100644 index 000000000000..b3fbfe7547cf --- /dev/null +++ b/java/java-psi-api/src/com/intellij/codeInsight/InferredAnnotationsManager.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2014 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.codeInsight; + +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.NotNullLazyKey; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiModifierListOwner; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public abstract class InferredAnnotationsManager { + private static final NotNullLazyKey<InferredAnnotationsManager, Project> INSTANCE_KEY = ServiceManager.createLazyKey(InferredAnnotationsManager.class); + + public static InferredAnnotationsManager getInstance(@NotNull Project project) { + return INSTANCE_KEY.getValue(project); + } + + @Nullable + public abstract PsiAnnotation findInferredAnnotation(@NotNull PsiModifierListOwner listOwner, @NotNull String annotationFQN); + + @NotNull + public abstract PsiAnnotation[] findInferredAnnotations(@NotNull PsiModifierListOwner listOwner); + + public abstract boolean isInferredAnnotation(@NotNull PsiAnnotation annotation); +} diff --git a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java index 192d19c31958..21e014e4aca3 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/NullableNotNullManager.java @@ -94,10 +94,15 @@ public class NullableNotNullManager implements PersistentStateComponent<Element> @Nullable public String getNullable(PsiModifierListOwner owner) { - PsiAnnotation annotation = findNullabilityAnnotation(owner, false, true); + PsiAnnotation annotation = getNullableAnnotation(owner, false); return annotation == null ? null : annotation.getQualifiedName(); } + @Nullable + public PsiAnnotation getNullableAnnotation(PsiModifierListOwner owner, boolean checkBases) { + return findNullabilityAnnotation(owner, checkBases, true); + } + public void setDefaultNullable(@NotNull String defaultNullable) { LOG.assertTrue(getNullables().contains(defaultNullable)); myDefaultNullable = defaultNullable; @@ -108,8 +113,13 @@ public class NullableNotNullManager implements PersistentStateComponent<Element> } @Nullable + public PsiAnnotation getNotNullAnnotation(PsiModifierListOwner owner, boolean checkBases) { + return findNullabilityAnnotation(owner, checkBases, false); + } + + @Nullable public String getNotNull(PsiModifierListOwner owner) { - PsiAnnotation annotation = findNullabilityAnnotation(owner, false, false); + PsiAnnotation annotation = getNotNullAnnotation(owner, false); return annotation == null ? null : annotation.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 fe45c66cf024..87afd3d4f8e4 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java @@ -44,7 +44,15 @@ public class PsiMethodReferenceUtil { public static String checkReturnType(PsiMethodReferenceExpression expression, JavaResolveResult result, PsiType functionalInterfaceType) { final PsiElement resolve = result.getElement(); if (resolve instanceof PsiMethod) { + final PsiClass containingClass = ((PsiMethod)resolve).getContainingClass(); + LOG.assertTrue(containingClass != null); PsiSubstitutor subst = result.getSubstitutor(); + PsiClass qContainingClass = getQualifierResolveResult(expression).getContainingClass(); + if (qContainingClass != null && InheritanceUtil.isInheritorOrSelf(qContainingClass, containingClass, true)) { + subst = TypeConversionUtil.getClassSubstitutor(containingClass, qContainingClass, subst); + LOG.assertTrue(subst != null); + } + final PsiType interfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType); @@ -57,7 +65,7 @@ public class PsiMethodReferenceUtil { PsiType methodReturnType = subst.substitute(returnType); if (interfaceReturnType != null && interfaceReturnType != PsiType.VOID) { if (methodReturnType == null) { - methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()).createType(((PsiMethod)resolve).getContainingClass(), subst); + methodReturnType = JavaPsiFacade.getElementFactory(expression.getProject()).createType(containingClass, subst); } if (!TypeConversionUtil.isAssignable(interfaceReturnType, methodReturnType, false)) { return "Bad return type in method reference: cannot convert " + methodReturnType.getCanonicalText() + " to " + interfaceReturnType.getCanonicalText(); 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 388da3b05ab9..622714c6dd61 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 @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 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. diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java index 472e7cd65403..885f1bd9a444 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiFormatUtil.java @@ -450,6 +450,40 @@ public class PsiFormatUtil extends PsiFormatUtilBase { return builder.toString(); } + @Nullable + public static String getRawExternalName(PsiModifierListOwner owner) { + final StringBuilder builder = new StringBuilder(); + final PsiClass psiClass = PsiTreeUtil.getParentOfType(owner, PsiClass.class, false); + if (psiClass == null) return null; + ClassUtil.formatClassName(psiClass, builder); + if (owner instanceof PsiMethod) { + builder.append(" "); + formatMethod((PsiMethod)owner, PsiSubstitutor.EMPTY, + SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_RAW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES, + SHOW_TYPE | SHOW_RAW_TYPE | SHOW_FQ_CLASS_NAMES, + Integer.MAX_VALUE, builder); + } + else if (owner instanceof PsiParameter) { + final PsiElement declarationScope = ((PsiParameter)owner).getDeclarationScope(); + if (!(declarationScope instanceof PsiMethod)) { + return null; + } + final PsiMethod psiMethod = (PsiMethod)declarationScope; + + builder.append(" "); + formatMethod(psiMethod, PsiSubstitutor.EMPTY, + SHOW_NAME | SHOW_FQ_NAME | SHOW_TYPE | SHOW_RAW_TYPE | SHOW_PARAMETERS | SHOW_FQ_CLASS_NAMES, + SHOW_TYPE | SHOW_RAW_TYPE | SHOW_FQ_CLASS_NAMES, + Integer.MAX_VALUE, builder); + builder.append(" "); + builder.append(psiMethod.getParameterList().getParameterIndex((PsiParameter)owner)); + } + else { + return null; + } + return builder.toString(); + } + public static String getPackageDisplayName(@NotNull final PsiClass psiClass) { if (psiClass instanceof PsiTypeParameter) { PsiTypeParameterListOwner owner = ((PsiTypeParameter)psiClass).getOwner(); diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java index 1a7e71c5fc69..b721d801b6c4 100644 --- a/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/util/PsiTypesUtil.java @@ -181,6 +181,7 @@ public class PsiTypesUtil { @Nullable public static PsiType createJavaLangClassType(@NotNull PsiElement context, @Nullable PsiType qualifierType, boolean captureTopLevelWildcards) { if (qualifierType != null) { + PsiUtil.ensureValidType(qualifierType); JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject()); PsiClass javaLangClass = facade.findClass(CommonClassNames.JAVA_LANG_CLASS, context.getResolveScope()); if (javaLangClass != null && javaLangClass.getTypeParameters().length == 1) { 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 b71214f907f0..e5493711b7c2 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 @@ -775,7 +775,7 @@ public final class PsiUtil extends PsiUtilCore { @NotNull public static Iterable<PsiTypeParameter> typeParametersIterable(@NotNull final PsiTypeParameterListOwner owner) { - ArrayList<PsiTypeParameter> result = null; + List<PsiTypeParameter> result = null; PsiTypeParameterListOwner currentOwner = owner; while (currentOwner != null) { |