You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Lint Detector的visitCallExpression方法中,判断Class类型参数的继承关系问题咨询

Fix: Correctly Check Subclass Inheritance for Class Literals in Lint Detector

I ran into exactly this issue before when building a custom Lint rule—your problem boils down to mixing up the java.lang.Class instance (represented by MyClass.class) with the actual MyClass type it references. Here's how to fix it:

The Root Cause

When you directly fetch a PsiClass from the MyClass.class expression, you're getting the PsiClass for java.lang.Class, not the MyClass type the literal points to. That's why InheritanceUtil.isInheritor always returns false—it’s checking if java.lang.Class extends MyParent, which it never will.

Step-by-Step Solution

You need to dig into the class literal expression to extract the underlying type (the MyClass part), then resolve that to its proper PsiClass. Here’s how to handle both Java and Kotlin code:

1. Identify Class Literal Arguments

First, in your visitCallExpression method, loop through the call’s arguments and check for class literals:

@Override
public void visitCallExpression(@NonNull UCallExpression call) {
    super.visitCallExpression(call);
    
    // Iterate over all arguments in the method call
    for (UExpression arg : call.getArguments()) {
        // Handle Java class literals (e.g., MyClass.class)
        if (arg instanceof UClassLiteralExpression) {
            handleJavaClassLiteral((UClassLiteralExpression) arg, call);
        } 
        // Handle Kotlin class literals (e.g., MyClass::class)
        else if (arg instanceof UKClassLiteralExpression) {
            handleKotlinClassLiteral((UKClassLiteralExpression) arg, call);
        }
    }
}

2. Resolve Java Class Literals to PsiClass

For Java code, use getType() on the UClassLiteralExpression to get the underlying type reference, then resolve it to a PsiClass:

private void handleJavaClassLiteral(UClassLiteralExpression classLiteral, UCallExpression call) {
    UType type = classLiteral.getType();
    if (type instanceof UDeclaredType) {
        PsiClass targetClass = ((UDeclaredType) type).resolve();
        if (targetClass != null) {
            // Now check inheritance against MyParent
            boolean isSubclass = InheritanceUtil.isInheritor(targetClass, "com.somePackage.MyParent");
            if (isSubclass) {
                // Insert your lint check/reporting logic here
                reportIssue(call, "MyClass is a subclass of MyParent");
            }
        }
    }
}

3. Resolve Kotlin Class Literals to PsiClass

For Kotlin, the UKClassLiteralExpression lets you access the referenced type via getTypeReference():

private void handleKotlinClassLiteral(UKClassLiteralExpression classLiteral, UCallExpression call) {
    UTypeReferenceExpression typeRef = classLiteral.getTypeReference();
    if (typeRef != null) {
        UType type = typeRef.getType();
        if (type instanceof UDeclaredType) {
            PsiClass targetClass = ((UDeclaredType) type).resolve();
            if (targetClass != null) {
                boolean isSubclass = InheritanceUtil.isInheritor(targetClass, "com.somePackage.MyParent");
                if (isSubclass) {
                    // Insert your lint check/reporting logic here
                }
            }
        }
    }
}

Key Notes

  • Always null-check the resolved PsiClass—there might be cases where the type can’t be resolved (e.g., missing dependencies, invalid code).
  • InheritanceUtil.isInheritor checks both direct and indirect inheritance, so it works for subclasses and nested subclasses alike.
  • Ensure you’re importing the correct Lint/PSI classes (e.g., com.android.tools.lint.detector.api.UClassLiteralExpression, com.intellij.psi.PsiClass).

This approach will let you properly check if MyClass is a subclass of MyParent instead of wasting cycles checking java.lang.Class.

内容的提问来源于stack exchange,提问作者Cozytrony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:43:09