package de.plushnikov.intellij.plugin.handler; import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiAnnotationParameterList; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiNameValuePair; import java.util.Arrays; import java.util.Collection; import java.util.regex.Pattern; public class OnXAnnotationHandler { private static final Pattern UNDERSCORES = Pattern.compile("__*"); private static final Pattern CANNOT_RESOLVE_UNDERSCORES_MESSAGE = Pattern.compile("Cannot resolve symbol '__*'"); private static final String ANNOTATION_TYPE_EXPECTED = "Annotation type expected"; private static final String CANNOT_FIND_METHOD_VALUE_MESSAGE = "Cannot find method 'value'"; private static final Collection<String> ONXABLE_ANNOTATIONS = Arrays.asList( "lombok.Getter", "lombok.Setter", "lombok.experimental.Wither", "lombok.NoArgsConstructor", "lombok.RequiredArgsConstructor", "lombok.AllArgsConstructor", "lombok.EqualsAndHashCode" ); private static final Collection<String> ONX_PARAMETERS = Arrays.asList( "onConstructor", "onMethod", "onParam" ); public static boolean isOnXParameterAnnotation(HighlightInfo highlightInfo, PsiFile file) { if (!(ANNOTATION_TYPE_EXPECTED.equals(highlightInfo.getDescription()) || CANNOT_RESOLVE_UNDERSCORES_MESSAGE.matcher(StringUtil.notNullize(highlightInfo.getDescription())).matches())) { return false; } PsiElement highlightedElement = file.findElementAt(highlightInfo.getStartOffset()); PsiNameValuePair nameValuePair = findContainingNameValuePair(highlightedElement); if (nameValuePair == null || !(nameValuePair.getContext() instanceof PsiAnnotationParameterList)) { return false; } String parameterName = nameValuePair.getName(); if (!ONX_PARAMETERS.contains(parameterName)) { return false; } PsiElement containingAnnotation = nameValuePair.getContext().getContext(); return containingAnnotation instanceof PsiAnnotation && ONXABLE_ANNOTATIONS.contains(((PsiAnnotation) containingAnnotation).getQualifiedName()); } public static boolean isOnXParameterValue(HighlightInfo highlightInfo, PsiFile file) { if (!CANNOT_FIND_METHOD_VALUE_MESSAGE.equals(highlightInfo.getDescription())) { return false; } PsiElement highlightedElement = file.findElementAt(highlightInfo.getStartOffset()); PsiNameValuePair nameValuePair = findContainingNameValuePair(highlightedElement); if (nameValuePair == null || !(nameValuePair.getContext() instanceof PsiAnnotationParameterList)) { return false; } PsiElement leftSibling = nameValuePair.getContext().getPrevSibling(); return (leftSibling != null && UNDERSCORES.matcher(StringUtil.notNullize(leftSibling.getText())).matches()); } private static PsiNameValuePair findContainingNameValuePair(PsiElement highlightedElement) { PsiElement nameValuePair = highlightedElement; while (!(nameValuePair == null || nameValuePair instanceof PsiNameValuePair)) { nameValuePair = nameValuePair.getContext(); } return (PsiNameValuePair) nameValuePair; } }