Hi everyone,I'm about to write a lint library to add to our company's projects. I already wrote some rules for Android specific classes like custom Fragments and Activities. That was pretty straightforward since I was able to list the superclasses from com/android/SdkConstants in my applicableSuperClasses() method.But I'm facing difficulties while writing tests for the Presenter/Interactor classes. I like to check if those extend from defined BasePresenter/BaseInteractor classes. But since those are all "plain objects" I have no specific superclass I can add to applicableSuperClasses() and the UastScanner won't visit anything.
@Nullable@Overridepublic List<String> applicableSuperClasses() {return Collections.singletonList("android.os.Parcelable");}Does that answer your question? (Sorry, I'm not very familiar with your use case; if you can include some code fragments showing the pattern you want to detect, I might be able to say something more useful.)-- Tor
public class InteractorNotExtendingBaseInteractor extends Detector implements UastScanner, Detector.ClassScanner {
public static final Issue ISSUE =
Issue.create("InteractorNotExtendingBaseInteractor", "Interactor should extend from BaseInteractor",
"Interactor implementations should extend from BaseInteractor.", Category.MESSAGES, 5, Severity.WARNING,
new Implementation(InteractorNotExtendingBaseInteractor.class, Scope.JAVA_FILE_SCOPE));
@Nullable @Override public List<String> applicableSuperClasses() {
// Not sure what to add in this case
return null;
}
@Override public void visitClass(@NonNull JavaContext context, @NonNull UClass declaration) {
if (declaration.getName() != null
&& !declaration.getName().equals("BaseInteractor")
&& !declaration.isInterface()
&& declaration.getName().endsWith("Interactor")
&& (declaration.getSuperClass() == null || !inheritsFromBaseInteractor(declaration))) {
context.report(ISSUE, declaration.getPsi(), context.getLocation(declaration.getPsi()),
"Interactor should to extend from BaseInteractor");
}
}
private boolean inheritsFromBaseInteractor(UClass declaration) {
boolean inherits = false;
while ((declaration != null ? declaration.getSuperClass() : null) != null) {
if (declaration.getSuperClass().getName() != null && declaration.getSuperClass()
.getName()
.equals("BaseInteractor")) {
inherits = true;
break;
}
}
return inherits;
}
@Override public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
}
}
@Override public List<String> applicableSuperClasses() {
return Arrays.asList(CLASS_FRAGMENT, CLASS_V4_FRAGMENT);
}
Thank you very much! Works like charm.But if I get it right, this method is the "slowest" approach to detect lint issues, since we have to travel through the whole syntax tree?