下面列出了com.intellij.psi.PsiTypeParameterList#org.jetbrains.uast.UAnnotation 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void reportMissingRetention(
@NotNull JavaContext context,
boolean isKotlin,
@NotNull UClass node,
@NotNull UAnnotation reflectRelatedAnnotation) {
context.report(
ISSUE_WRONG_RETENTION,
node,
context.getNameLocation(node),
"Annotation used by Dagger Reflect must be annotated with `@Retention(RUNTIME)`.",
LintFix.create()
.replace()
.name("Add: `@Retention(RUNTIME)`")
.range(context.getLocation(reflectRelatedAnnotation))
.beginning()
.with(isKotlin ? FIX_ANNOTATION_RETENTION_KOTLIN : FIX_ANNOTATION_RETENTION_JAVA)
.reformat(true)
.shortenNames()
.build());
}
private static void reportWrongRetentionType(
@NotNull JavaContext context,
boolean isKotlin,
@NotNull UAnnotation retentionAnnotation,
@NotNull String actualRetention) {
final UExpression annotationValue = UastLintUtils.getAnnotationValue(retentionAnnotation);
context.report(
ISSUE_WRONG_RETENTION,
retentionAnnotation,
context.getLocation(retentionAnnotation),
String.format(
"Annotation used by Dagger Reflect must be annotated with `@Retention(RUNTIME)` but is `@Retention(%s)`.",
actualRetention),
LintFix.create()
.name("Replace with: `@Retention(RUNTIME)`")
.replace()
.range(context.getLocation(annotationValue))
.with(isKotlin ? FIX_RETENTION_TYPE_KOTLIN : FIX_RETENTION_TYPE_JAVA)
.reformat(true)
.shortenNames()
.build());
}
@Override
protected void visitDefaultConfigAnnotation(final UAnnotation node, final PsiElement defaultConfig) {
if (!ConfigElementsUtils.isConfigFieldReference(defaultConfig)) {
return;
}
final UField configField = (UField) node.getUastParent();
final String configFieldType = ConfigElementsUtils.getConfigFieldType(configField);
if (configFieldType == null) {
return;
}
final String defaultValueConfigFieldType = ConfigElementsUtils.getConfigFieldType(ElementUtils.getReferencedField(defaultConfig));
if (!configFieldType.equals(defaultValueConfigFieldType)) {
report(node);
}
}
@Override
protected void visitConfigTypeAnnotation(final UAnnotation node, final UClass owner) {
final List<UAnnotation> annotations = ((UAnnotated) owner).getAnnotations();
for (UAnnotation annotation : annotations) {
if (!isRetentionAnnotation(annotation)) {
continue;
}
final RetentionPolicy retentionPolicy = getRetentionPolicyValue(annotation);
if (retentionPolicy == RetentionPolicy.RUNTIME) {
return;
}
}
reportPsi(owner.getNameIdentifier());
}
@Override
protected void visitConfigTypeAnnotation(final UAnnotation node, final UClass owner) {
final UMethod defaultValueMethod = getDefaultValueMethod(owner);
if (defaultValueMethod == null) {
return;
}
final PsiType type = defaultValueMethod.getReturnType();
if (isOneOfTypes(type, String.class, Float.class, Integer.class, Long.class, Boolean.class)) {
return;
}
final String typeName = type.getCanonicalText();
if (typeName.equals(PRIMITIVE_FLOAT) || typeName.equals(PRIMITIVE_INT) || typeName.equals(PRIMITIVE_LONG) || typeName.equals(PRIMITIVE_BOOLEAN)) {
return;
}
log(typeName);
reportPsi(owner.getNameIdentifier());
}
@Override
protected void visitConfigTypeAnnotation(final UAnnotation node, final UClass owner) {
final List<UAnnotation> annotations = ((UAnnotated) owner).getAnnotations();
for (UAnnotation annotation : annotations) {
if (!isTargetAnnotation(annotation)) {
continue;
}
final ElementType[] annotationTargets = getTargetValue(annotation);
if (annotationTargets.length == 1 && annotationTargets[0] == ElementType.FIELD) {
return;
}
}
reportPsi(owner.getNameIdentifier());
}
@Override
public final void visit(final UAnnotation node) {
final PsiAnnotation nodePsi = node.getJavaPsi();
if (nodePsi == null || !ConfigElementsUtils.isJsonConfigAnnotation(nodePsi)) {
return;
}
final PsiClass jsonType = ConfigElementsUtils.getJsonTypeAttribute(nodePsi);
if (jsonType == null) {
return;
}
final int genericTypesCount = ConfigElementsUtils.getGenericTypesCount(nodePsi);
visitJsonConfigAnnotation(node, jsonType, genericTypesCount);
}
@Override
protected void visitEnumConfigAnnotation(final UAnnotation node, final PsiClass enumClass) {
final PsiField[] fields = enumClass.getFields();
if (fields.length == 0) {
report(node);
return;
}
for (PsiField psiField : fields) {
if (ElementUtils.isEnumConst(psiField) && !ConfigElementsUtils.hasRemoteValueAnnotation(psiField)) {
report(node);
return;
}
}
}
@Override
protected void visitEnumConfigAnnotation(final UAnnotation node, final PsiClass enumClass) {
final List<Object> remoteValues = new ArrayList<>();
for (PsiField psiField : enumClass.getFields()) {
final Object remoteValue = ConfigElementsUtils.getRemoteValue(psiField);
if (remoteValue == null) {
return;
}
remoteValues.add(remoteValue);
}
final Object defaultValue = ConfigElementsUtils.getDefaultValueAttribute(node.getJavaPsi());
if (!remoteValues.contains(defaultValue)) {
report(node, getIssueExplanation() + " " + Arrays.toString(remoteValues.toArray()));
}
}
@Override
public boolean visitAnnotation(UAnnotation node) {
if (!context.isEnabled(ISSUE)) {
return true;
}
// Let's store NeedsPermission and OnShowRationale
String type = node.getQualifiedName();
if ("permissions.dispatcher.NeedsPermission".equals(type)) {
needsPermissionAnnotations.add(node);
} else if ("permissions.dispatcher.OnShowRationale".equals(type)) {
onShowRationaleAnnotations.add(node);
}
if (onShowRationaleAnnotations.isEmpty()) {
return true;
}
return true;
}
@Override
public boolean visitMethod(@NotNull UMethod node) {
if (isGeneratedFiles(context)) {
return super.visitMethod(node);
}
UAnnotation annotation = node.findAnnotation("permissions.dispatcher.NeedsPermission");
if (annotation == null) {
return super.visitMethod(node);
}
String methodIdentifier = methodIdentifier(node);
if (methodIdentifier == null) {
return super.visitMethod(node);
}
annotatedMethods.add(methodIdentifier);
return super.visitMethod(node);
}
@Override
public UElementHandler createUastHandler(@NotNull JavaContext context) {
return new UElementHandler() {
@Override
public void visitClass(@NotNull UClass node) {
if (!node.isAnnotationType()) {
return;
}
final UAnnotation qualifierAnnotation = node.findAnnotation(ANNOTATION_QUALIFIER);
final UAnnotation mapKeyAnnotation = node.findAnnotation(ANNOTATION_MAP_KEY);
if (qualifierAnnotation == null && mapKeyAnnotation == null) {
return;
}
final boolean isKotlin = Lint.isKotlin(node);
final UAnnotation retentionAnnotation =
node.findAnnotation(isKotlin ? ANNOTATION_RETENTION_KOTLIN : ANNOTATION_RETENTION_JAVA);
if (retentionAnnotation == null) {
final UAnnotation reflectRelatedAnnotation =
qualifierAnnotation != null ? qualifierAnnotation : mapKeyAnnotation;
reportMissingRetention(context, isKotlin, node, reflectRelatedAnnotation);
} else {
final String retentionPolicy = getRetentionPolicy(context, isKotlin, retentionAnnotation);
if (!"RUNTIME".equals(retentionPolicy)) {
reportWrongRetentionType(context, isKotlin, retentionAnnotation, retentionPolicy);
}
}
}
};
}
@NotNull
private static String getRetentionPolicy(
@NotNull JavaContext context, boolean isKotlin, @NotNull UAnnotation retentationAnnotation) {
final UExpression annotationValue = UastLintUtils.getAnnotationValue(retentationAnnotation);
final String retentionPolicyQualifiedName =
isKotlin
? getQualifiedNameForValueKotlin(context, annotationValue)
: getQualifiedNameForValueJava(context, annotationValue);
final String retentionPolicy = getRetentionPolicyForQualifiedName(retentionPolicyQualifiedName);
if (retentionPolicy != null) {
return retentionPolicy;
}
throw new IllegalStateException("RetentionPolicy must not be null if @Retention is present");
}
@Override
public boolean visitAnnotation(@NotNull final UAnnotation node) {
if (node.getJavaPsi() != null) {
for (IssueDetector issueDetector : mIssueDetectors) {
issueDetector.visit(node);
}
}
return super.visitAnnotation(node);
}
@Override
public void visit(final UMethod node) {
final UAnnotation defaultValueProviderAnnotation = ConfigElementsUtils.getDefaultValueProviderAnnotation(node);
if (defaultValueProviderAnnotation == null) {
return;
}
final PsiElement referencedConfig = defaultValueProviderAnnotation.findAttributeValue(null)
.getJavaPsi();
final PsiField referencedField = ElementUtils.getReferencedField(referencedConfig);
mConfigFieldsWithDefaultValues.add(referencedField);
}
@Override
protected void visitDefaultConfigAnnotation(final UAnnotation node, final PsiElement defaultConfig) {
final UField configField = (UField) node.getUastParent();
final boolean cyclicDefaultValueConfigReference = hasCyclicDefaultValueConfigReference(configField, new ArrayList<>(Collections.singletonList(configField.getPsi())));
if (cyclicDefaultValueConfigReference) {
report(node);
}
}
@Override
public void visit(final UAnnotation node) {
if (!ConfigElementsUtils.isDefaultConfigAnnotation(node)) {
return;
}
final PsiElement defaultConfig = node.findAttributeValue(null)
.getJavaPsi();
visitDefaultConfigAnnotation(node, defaultConfig);
}
@Override
public void visit(final UAnnotation node) {
if (!ConfigElementsUtils.isConfigAttributeAnnotation(node)) {
return;
}
final PsiField field = (PsiField) node.getUastParent()
.getJavaPsi();
if (!ConfigElementsUtils.isConfigField(field) || ConfigElementsUtils.isConfigGroupField(field)) {
report(node, "**@" + getSimpleName(node) + "** " + ISSUE.getExplanation(TextFormat.TEXT));
}
}
@Override
protected void visitConfigAuxAnnotation(final UAnnotation node) {
final PsiElement value = node.findAttributeValue(null)
.getJavaPsi();
if (!ConfigElementsUtils.isConfigFieldReference(value)) {
report(node);
}
}
@Override
public void visit(final UAnnotation node) {
if (!ConfigElementsUtils.isConfigAuxAnnotation(node)) {
return;
}
visitConfigAuxAnnotation(node);
}
private ElementType[] getTargetValue(final UAnnotation annotation) {
final UNamedExpression attributeValue = annotation.getAttributeValues()
.get(0);
final Object targetValue = attributeValue.getExpression()
.evaluate();
if (targetValue instanceof ElementType[]) {
return (ElementType[]) targetValue;
}
else {
return new ElementType[]{(ElementType) targetValue};
}
}
@Override
protected void visitConfigTypeAnnotation(final UAnnotation node, final UClass owner) {
final PsiClass resolverClass = ((PsiImmediateClassType) node.getAttributeValues()
.get(0)
.getExpression()
.evaluate()).resolve();
final PsiClassType resolverClassType = getConfigTypeResolverClassType(resolverClass);
if (resolverClassType == null) {
return;
}
final PsiType annotationType = getAnnotationType(resolverClassType);
final PsiType rawType = getRawType(resolverClassType);
if (!annotationType.getCanonicalText()
.equals(owner.getQualifiedName())) {
report(node);
return;
}
final UMethod defaultValueMethod = getDefaultValueMethod(owner);
if (defaultValueMethod == null) {
return;
}
if (!rawType.equals(defaultValueMethod.getReturnType())) {
report(node);
}
}
@Override
public final void visit(final UAnnotation node) {
if (!ElementUtils.isOfType(node.getJavaPsi(), ConfigType.class)) {
return;
}
visitConfigTypeAnnotation(node, (UClass) node.getUastParent());
}
@Override
protected void visitConfigGroupAnnotation(final UAnnotation node) {
final PsiArrayInitializerMemberValue configGroupValues = ConfigElementsUtils.getConfigGroupValuesAttribute(node.getJavaPsi());
if (configGroupValues.getInitializers().length == 0) {
report(node);
}
}
@Override
protected void visitConfigGroupAnnotation(final UAnnotation node) {
final PsiArrayInitializerMemberValue configGroupValues = ConfigElementsUtils.getConfigGroupValuesAttribute(node.getJavaPsi());
for (PsiAnnotationMemberValue psiAnnotationMemberValue : configGroupValues.getInitializers()) {
if (!verifyConfigFieldReference(node, psiAnnotationMemberValue)) {
return;
}
}
}
@Override
protected void visitConfigGroupAnnotation(final UAnnotation node) {
final PsiField configField = ((UField) node.getUastParent()).getPsi();
if (hasCyclicConfigGroupReference(configField, new ArrayList<>(Collections.singletonList(configField)))) {
report(node);
}
}
@Override
public final void visit(final UAnnotation node) {
if (!ConfigElementsUtils.isConfigGroupAnnotation(node)) {
return;
}
visitConfigGroupAnnotation(node);
}
@Override
protected void visitJsonConfigAnnotation(final UAnnotation node, final PsiClass jsonType, final int genericTypesCount) {
final PsiTypeParameterList typeParameterList = jsonType.getTypeParameterList();
final int expectedGenericTypesCount = typeParameterList != null ? typeParameterList.getTypeParameters().length : 0;
if (expectedGenericTypesCount != genericTypesCount) {
report(node, String.format(Locale.getDefault(), DESC_FORMAT, jsonType.getName(), expectedGenericTypesCount, genericTypesCount));
}
}
@Override
public final void visit(final UAnnotation node) {
if (!ConfigElementsUtils.isEnumConfigAnnotation(node.getJavaPsi())) {
return;
}
final PsiClass enumClass = ConfigElementsUtils.getEnumClassAttribute(node.getJavaPsi());
visitEnumConfigAnnotation(node, enumClass);
}
public static UAnnotation getDefaultValueProviderAnnotation(UMethod method) {
for (UAnnotation annotation : ((UAnnotated) method).getAnnotations()) {
if (ElementUtils.isOfType(annotation.getJavaPsi(), ConfigDefaultValueProvider.class)) {
return annotation;
}
}
return null;
}