我正试图在我的Android代码中创建一个Lint规则,以检查构造函数中的注入数,因此,如果我超过了视图模型的某个数字,我将提出一个lint警告。
我知道我必须在Lint检测器中实现一个UastScanner,但是我迷路了,因为我找不到好的文档。其他人做过这样的事吗?或者我在哪里能找到好的脱眼方法呢?
谢谢!
发布于 2017-12-14 20:58:32
*备注-阅读编辑的解决方案的全部答案。*
我能够像这样编写UAST转换:
public class NumberOfDependenciesInjectedDetector extends Detector implements Detector.UastScanner {
private static final int NUMBER_OF_INJECTIONS_ALLOWED = 5;
private static final Class<? extends Detector> DETECTOR = NumberOfDependenciesInjectedDetector.class;
private static final EnumSet<Scope> SCOPE = Scope.JAVA_FILE_SCOPE;
private static final Implementation IMPLEMENTATION = new Implementation(DETECTOR, SCOPE);
public static final Issue ISSUE = Issue.create(
"NumberOfDependenciesInjected",
"Limit number of injections in a class via constructor",
"A longer description here",
Category.CORRECTNESS,
10,
Severity.ERROR,
IMPLEMENTATION
);
@Override
public List<Class<? extends UElement>> getApplicableUastTypes() {
return Collections.<Class<? extends UElement>>singletonList(UClass.class);
}
@Override
public UElementHandler createUastHandler(JavaContext context) {
return new ConstructorVisitor(context);
}
private static class ConstructorVisitor extends UElementHandler {
private JavaContext javaContext;
private ConstructorVisitor(JavaContext javaContext) {
this.javaContext = javaContext;
}
@Override
public void visitClass(UClass clazz){
UMethod[] methods = clazz.getMethods();
for(UMethod method : methods){
if(!method.isConstructor()) continue;
if (method.getParameterList().getParametersCount() > NUMBER_OF_INJECTIONS_ALLOWED) {
javaContext.report(ISSUE, method, javaContext.getLocation(method), "Injections exceed allowed value of " + NUMBER_OF_INJECTIONS_ALLOWED);
}
}
}
}
}不过,似乎这还没有找到Kotlin源文件..。非常令人困惑。
编辑: 12/19/17 -固定
问题有两方面:
1) Psi方法确实有一种隐藏的用法,它阻碍了检查的工作。visitClass方法不应该使用getParameterList(),而应该使用getUastParameters()。以上客舱改为:
@Override
public void visitClass(UClass clazz){
UMethod[] methods = clazz.getMethods();
for(UMethod method : methods){
if(!method.isConstructor()) continue;
if (method.getUastParameters().size() > NUMBER_OF_INJECTIONS_ALLOWED) {
javaContext.report(ISSUE, clazz, javaContext.getLocation(method), "Injections exceed allowed value of " + NUMBER_OF_INJECTIONS_ALLOWED);
}
}
}2)在直接在lint组上与托尔·诺拜交谈后,他指出,AndroidStudio3.0实际上并不适用于kotlin,因此不能像这里所描述的那样工作。升级到AndroidStudio3.1Canary并运行linter产生了预期的报告。
发布于 2017-12-14 17:37:53
因此,我能够使用JavaScanner找到解决方案,但还没有找到任何使用UastScanner的解决方案(这正是我想要使用的,因为我们也有Kotlin类):
public class NumberOfDependenciesInjectedDetector extends Detector implements Detector.JavaScanner {
private static final int NUMBER_OF_INJECTIONS_ALLOWED = 5;
private static final Class<? extends Detector> DETECTOR = NumberOfDependenciesInjectedDetector.class;
private static final EnumSet<Scope> SCOPE = Scope.JAVA_FILE_SCOPE;
private static final Implementation IMPLEMENTATION = new Implementation(DETECTOR, SCOPE);
public static final Issue ISSUE = Issue.create(
"NumberOfDependenciesInjected",
"Limit number of injections in a class via constructor",
"A longer description here",
Category.CORRECTNESS,
10,
Severity.ERROR,
IMPLEMENTATION
);
@Override
public boolean appliesTo(Context context, File file) {
return true;
}
@Override
public Speed getSpeed(Issue issue) {
return Speed.FAST;
}
@Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
return Collections.<Class<? extends Node>>singletonList(ConstructorDeclaration.class);
}
@Override
public AstVisitor createJavaVisitor(JavaContext context) {
return new ConstructorVisitor(context);
}
private static class ConstructorVisitor extends ForwardingAstVisitor {
private JavaContext javaContext;
private ConstructorVisitor(JavaContext javaContext) {
this.javaContext = javaContext;
}
@Override
public boolean visitConstructorDeclaration(ConstructorDeclaration node) {
if (node.astParameters().size() > NUMBER_OF_INJECTIONS_ALLOWED) {
javaContext.report(ISSUE, node, javaContext.getLocation(node), "My message goes here");
return true;
}
return false;
}
}
}https://stackoverflow.com/questions/47704372
复制相似问题