@Nullable public static PsiAnnotation getAnnotation( @NotNull PsiModifierListOwner field, @NotNull String annotationName) { final PsiModifierList modifierList = field.getModifierList(); if (modifierList == null) return null; return modifierList.findAnnotation(annotationName); }
/** * Returns a set of targets where the given annotation may be applied, or {@code null} when the * type is not a valid annotation. */ @Nullable public static Set<TargetType> getAnnotationTargets(@NotNull PsiClass annotationType) { if (!annotationType.isAnnotationType()) return null; PsiModifierList modifierList = annotationType.getModifierList(); if (modifierList == null) return null; PsiAnnotation target = modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET); if (target == null) return DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8 // TYPE_USE/TYPE_PARAMETERS targets return extractRequiredAnnotationTargets(target.findAttributeValue(null)); }
public static boolean isAnnotatedCheckHierarchyWithCache( @NotNull PsiClass aClass, @NotNull String annotationFQN) { Map<String, PsiClass> classMap = getSuperClassesWithCache(aClass); for (PsiClass psiClass : classMap.values()) { PsiModifierList modifierList = psiClass.getModifierList(); if (modifierList != null) { if (modifierList.findAnnotation(annotationFQN) != null) { return true; } } } return false; }
@Override public void invoke( @NotNull Project project, @NotNull PsiFile file, @Nullable("is null when called from inspection") Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { final PsiModifierListOwner myModifierListOwner = (PsiModifierListOwner) startElement; final ExternalAnnotationsManager annotationsManager = ExternalAnnotationsManager.getInstance(project); final PsiModifierList modifierList = myModifierListOwner.getModifierList(); LOG.assertTrue(modifierList != null); if (modifierList.findAnnotation(myAnnotation) != null) return; final ExternalAnnotationsManager.AnnotationPlace annotationAnnotationPlace = annotationsManager.chooseAnnotationsPlace(myModifierListOwner); if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.NOWHERE) return; if (annotationAnnotationPlace == ExternalAnnotationsManager.AnnotationPlace.EXTERNAL) { for (String fqn : myAnnotationsToRemove) { annotationsManager.deannotate(myModifierListOwner, fqn); } annotationsManager.annotateExternally(myModifierListOwner, myAnnotation, file, myPairs); } else { final PsiFile containingFile = myModifierListOwner.getContainingFile(); if (!CodeInsightUtilBase.preparePsiElementForWrite(containingFile)) return; for (String fqn : myAnnotationsToRemove) { PsiAnnotation annotation = AnnotationUtil.findAnnotation(myModifierListOwner, fqn); if (annotation != null) { annotation.delete(); } } PsiAnnotation inserted = modifierList.addAnnotation(myAnnotation); for (PsiNameValuePair pair : myPairs) { inserted.setDeclaredAttributeValue(pair.getName(), pair.getValue()); } JavaCodeStyleManager.getInstance(project).shortenClassReferences(inserted); if (containingFile != file) { UndoUtil.markPsiFileForUndo(file); } } }
@Nullable private static RetentionPolicy getRetentionPolicy(PsiClass annotation) { PsiModifierList modifierList = annotation.getModifierList(); if (modifierList != null) { PsiAnnotation retentionAnno = modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_RETENTION); if (retentionAnno == null) return RetentionPolicy.CLASS; PsiAnnotationMemberValue policyRef = PsiImplUtil.findAttributeValue(retentionAnno, null); if (policyRef instanceof PsiReference) { PsiElement field = ((PsiReference) policyRef).resolve(); if (field instanceof PsiEnumConstant) { String name = ((PsiEnumConstant) field).getName(); try { return RetentionPolicy.valueOf(name); } catch (Exception e) { LOG.warn("Unknown policy: " + name); } } } } return null; }
public static boolean modifierListsAreEquivalent( @Nullable PsiModifierList list1, @Nullable PsiModifierList list2) { if (list1 == null) { return list2 == null; } else if (list2 == null) { return false; } final PsiAnnotation[] annotations = list1.getAnnotations(); for (PsiAnnotation annotation : annotations) { final String qualifiedName = annotation.getQualifiedName(); if (qualifiedName == null) { return false; } if (list2.findAnnotation(qualifiedName) == null) { return false; } } if (list1.hasModifierProperty(PsiModifier.ABSTRACT) && !list2.hasModifierProperty(PsiModifier.ABSTRACT)) { return false; } if (list1.hasModifierProperty(PsiModifier.FINAL) && !list2.hasModifierProperty(PsiModifier.FINAL)) { return false; } if (list1.hasModifierProperty(PsiModifier.NATIVE) && !list2.hasModifierProperty(PsiModifier.NATIVE)) { return false; } if (list1.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && !list2.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { return false; } if (list1.hasModifierProperty(PsiModifier.PRIVATE) && !list2.hasModifierProperty(PsiModifier.PRIVATE)) { return false; } if (list1.hasModifierProperty(PsiModifier.PROTECTED) && !list2.hasModifierProperty(PsiModifier.PROTECTED)) { return false; } if (list1.hasModifierProperty(PsiModifier.PUBLIC) && !list2.hasModifierProperty(PsiModifier.PUBLIC)) { return false; } if (list1.hasModifierProperty(PsiModifier.STATIC) && !list2.hasModifierProperty(PsiModifier.STATIC)) { return false; } if (list1.hasModifierProperty(PsiModifier.STRICTFP) && !list2.hasModifierProperty(PsiModifier.STRICTFP)) { return false; } if (list1.hasModifierProperty(PsiModifier.SYNCHRONIZED) && !list2.hasModifierProperty(PsiModifier.SYNCHRONIZED)) { return false; } if (list1.hasModifierProperty(PsiModifier.TRANSIENT) && !list2.hasModifierProperty(PsiModifier.TRANSIENT)) { return false; } return !(list1.hasModifierProperty(PsiModifier.VOLATILE) && !list2.hasModifierProperty(PsiModifier.VOLATILE)); }
public static boolean isDeprecatedByAnnotation(@NotNull PsiModifierListOwner owner) { PsiModifierList modifierList = owner.getModifierList(); return modifierList != null && modifierList.findAnnotation("java.lang.Deprecated") != null; }
@Override public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { if (!MinecraftSettings.Companion.getInstance().isShowEventListenerGutterIcons()) { return; } // Since we want to line up with the method declaration, not the annotation // declaration, we need to target identifiers, not just PsiMethods. if (!(element instanceof PsiIdentifier && (element.getParent() instanceof PsiMethod))) { return; } // The PsiIdentifier is going to be a method of course! PsiMethod method = (PsiMethod) element.getParent(); if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { // I don't think any implementation allows for abstract return; } PsiModifierList modifierList = method.getModifierList(); Module module = ModuleUtilCore.findModuleForPsiElement(element); if (module == null) { return; } MinecraftModule instance = MinecraftModule.getInstance(module); if (instance == null) { return; } // Since each platform has their own valid listener annotations, // some platforms may have multiple allowed annotations for various cases final Collection<AbstractModuleType<?>> moduleTypes = instance.getTypes(); boolean contains = false; for (AbstractModuleType<?> moduleType : moduleTypes) { final List<String> listenerAnnotations = moduleType.getListenerAnnotations(); for (String listenerAnnotation : listenerAnnotations) { if (modifierList.findAnnotation(listenerAnnotation) != null) { contains = true; break; } } } if (!contains) { return; } final PsiParameter[] parameters = method.getParameterList().getParameters(); if (parameters.length < 1) { return; } final PsiParameter eventParameter = parameters[0]; if (eventParameter == null) { // Listeners must have at least a single parameter return; } // Get the type of the parameter so we can start resolving it PsiTypeElement psiEventElement = eventParameter.getTypeElement(); if (psiEventElement == null) { return; } final PsiType type = psiEventElement.getType(); // Validate that it is a class reference type, I don't know if this will work with // other JVM languages such as Kotlin or Scala, but it might! if (!(type instanceof PsiClassReferenceType)) { return; } // And again, make sure that we can at least resolve the type, otherwise it's not a valid // class reference. final PsiClass eventClass = ((PsiClassReferenceType) type).resolve(); if (eventClass == null) { return; } if (instance.isEventClassValid(eventClass, method)) { return; } if (!instance.isStaticListenerSupported(eventClass, method) && method.hasModifierProperty(PsiModifier.STATIC)) { if (method.getNameIdentifier() != null) { holder.createErrorAnnotation( method.getNameIdentifier(), "Event listener method must not be static"); } } if (!isSuperEventListenerAllowed(eventClass, method, instance)) { holder.createErrorAnnotation( eventParameter, instance.writeErrorMessageForEvent(eventClass, method)); } }
@Override public void collectMethods( @NotNull GrTypeDefinition typeDefinition, Collection<PsiMethod> collector) { if (typeDefinition.getName() == null) return; PsiModifierList modifierList = typeDefinition.getModifierList(); if (modifierList == null) return; final PsiAnnotation tupleConstructor = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_TUPLE_CONSTRUCTOR); final boolean immutable = modifierList.findAnnotation(IMMUTABLE) != null || modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_IMMUTABLE) != null; final PsiAnnotation canonical = modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_CANONICAL); if (!immutable && canonical == null && tupleConstructor == null) { return; } if (tupleConstructor != null && typeDefinition.getCodeConstructors().length > 0 && !PsiUtil.getAnnoAttributeValue(tupleConstructor, "force", false)) { return; } final GrLightMethodBuilder fieldsConstructor = new GrLightMethodBuilder(typeDefinition.getManager(), typeDefinition.getName()); fieldsConstructor.setConstructor(true).setNavigationElement(typeDefinition); Set<String> excludes = new HashSet<String>(); if (tupleConstructor != null) { for (String s : PsiUtil.getAnnoAttributeValue(tupleConstructor, "excludes", "").split(",")) { final String name = s.trim(); if (StringUtil.isNotEmpty(name)) { excludes.add(name); } } } if (tupleConstructor != null) { final boolean superFields = PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeSuperFields", false); final boolean superProperties = PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeSuperProperties", false); if (superFields || superProperties) { addParametersForSuper( typeDefinition, fieldsConstructor, superFields, superProperties, new HashSet<PsiClass>(), excludes); } } addParameters( typeDefinition, fieldsConstructor, tupleConstructor == null || PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeProperties", true), tupleConstructor != null ? PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeFields", false) : canonical == null, !immutable, excludes); collector.add(fieldsConstructor.setContainingClass(typeDefinition)); collector.add( new GrLightMethodBuilder(typeDefinition.getManager(), typeDefinition.getName()) .addParameter("args", CommonClassNames.JAVA_UTIL_MAP, false) .setConstructor(true) .setContainingClass(typeDefinition)); }
public static boolean checkModifierProperty( @NotNull GrModifierList modifierList, @GrModifier.GrModifierConstant @NotNull String modifier) { final PsiElement owner = modifierList.getParent(); if (owner instanceof GrVariableDeclaration && owner.getParent() instanceof GrTypeDefinitionBody) { PsiElement pParent = owner.getParent().getParent(); if (!modifierList .hasExplicitVisibilityModifiers()) { // properties are backed by private fields if (!(pParent instanceof PsiClass) || !((PsiClass) pParent).isInterface()) { if (modifier.equals(GrModifier.PRIVATE)) return true; if (modifier.equals(GrModifier.PROTECTED)) return false; if (modifier.equals(GrModifier.PUBLIC)) return false; } } if (pParent instanceof PsiClass && ((PsiClass) pParent).isInterface()) { if (modifier.equals(GrModifier.STATIC)) return true; if (modifier.equals(GrModifier.FINAL)) return true; } if (pParent instanceof GrTypeDefinition) { PsiModifierList pModifierList = ((GrTypeDefinition) pParent).getModifierList(); if (pModifierList != null && pModifierList.findAnnotation(ConstructorAnnotationsProcessor.IMMUTABLE) != null) { if (modifier.equals(GrModifier.FINAL)) return true; } } } // top level classes cannot have private and protected modifiers if (owner instanceof GrTypeDefinition && ((GrTypeDefinition) owner).getContainingClass() == null) { if (modifier.equals(PROTECTED) || modifier.equals(PRIVATE)) return false; if (modifier.equals(PACKAGE_LOCAL)) return modifierList.hasExplicitModifier(PRIVATE) || modifierList.hasExplicitModifier(PROTECTED); } if (modifierList.hasExplicitModifier(modifier)) { return true; } if (modifier.equals(GrModifier.PUBLIC)) { if (owner instanceof GrPackageDefinition) return false; if (owner instanceof GrVariableDeclaration && !(owner.getParent() instanceof GrTypeDefinitionBody) || owner instanceof GrVariable) { return false; } // groovy type definitions and methods are public by default return !modifierList.hasExplicitModifier(GrModifier.PRIVATE) && !modifierList.hasExplicitModifier(GrModifier.PROTECTED); } if (owner instanceof GrTypeDefinition) { if (modifier.equals(GrModifier.STATIC)) { final PsiClass containingClass = ((GrTypeDefinition) owner).getContainingClass(); return containingClass != null && containingClass.isInterface(); } if (modifier.equals(GrModifier.ABSTRACT)) { return ((GrTypeDefinition) owner).isInterface(); } } return false; }