
效果圖
源碼ParcelDetector.java
ParcelDetector實(shí)現(xiàn)了JavaPsiScanner java文件檢測接口
核心代碼
@Nullable
@Override
public List<String> applicableSuperClasses() {
return Collections.singletonList(CLASS_PARCELABLE);
}
@Override
public void checkClass(@NonNull JavaContext context, @NonNull PsiClass declaration) {
if (declaration instanceof PsiAnonymousClass) {
// Anonymous classes aren't parcelable
return;
}
// Only applies to concrete classes
if (declaration.isInterface()) {
return;
}
if (declaration.hasModifierProperty(PsiModifier.ABSTRACT)) {
return;
}
// Parceling spans is handled in TextUtils#CHAR_SEQUENCE_CREATOR
if (context.getEvaluator().implementsInterface(declaration,
"android.text.ParcelableSpan", false)) {
return;
}
PsiField field = declaration.findFieldByName("CREATOR", true);
if (field == null) {
Location location = context.getNameLocation(declaration);
context.report(ISSUE, declaration, location,
"This class implements `Parcelable` but does not "
+ "provide a `CREATOR` field");
}
}
實(shí)現(xiàn)函數(shù)解析
-
applicableSuperClasses
這個方法用來返回你感興趣的那些父類,所以這里android.os.Parcelable(SdkConstants.CLASS_PARCELABLE ),此方法配合以下方法使用
-
checkClass(JavaContext context,PsiClass declaration)
檢測到父類為以上指定的類是會觸發(fā)此方法
判斷是不是注解類 declaration instanceof PsiAnonymousClass
判斷是不是接口declaration.isInterface()
判斷是不是抽象類declaration.hasModifierProperty(PsiModifier.ABSTRACT)
-
判斷PsiClass是否實(shí)現(xiàn)指定接口
JavaEvaluator.implementsInterface(PsiClass cls,String interfaceName,boolean strict)- interfaceName 接口名稱如:android.text.ParcelableSpan
- strict 不清楚(大多數(shù)代碼都是false)
-
獲取成員變量PsiClass.findFieldByName(String name, boolean checkBases)
- name 變量名
- 是否校驗(yàn)父類