针对构造函数中注入次数的Lint规则
我试图在我的Android代码中创建一个Lint规则,检查构造函数中是否注入数字,所以如果我为视图模型超过了某个数字,例如,我将引发一个lint警告。
我知道我必须在我的Lint探测器中实施一个UastScanner,但是我迷路了,因为我找不到好的文档。 还有别人做过这样的事吗? 或者我可以在哪里find好的文档?
谢谢!
所以我能够使用JavaScannerfind一个解决方案,但是我还没有发现任何使用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.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> getApplicableNodeTypes() { return Collections.>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; } } }
*注 – 阅读编辑解决方案的完整答案。 *
我能够像这样写出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.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> getApplicableUastTypes() { return Collections.>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()。 将上面的visitclass替换为:
@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)在与Tor Norbye直接在lint-dev组谈话之后,他指出Android Studio 3.0的lint实际上并不与kotlin一起工作,因此不会像这里描述的那样工作。 升级到Android Studio 3.1 Canary并运行linter产生了预期的报告。
- 如何在GraphView库中添加一系列DataPoint?
- 如何在Android上用Kotlin替换一个FrameLayout
- 无法在RealmObject子类中创建ArrayList
- 领域executeTransactionAsync不写入数据到数据库
- 将像素转换为dp
- Realm插件导致“app:compileInstantrunconfigDebugKotlin”任务失败
- 如何区分绑定的可调用成员引用和kotlin中相同types的函数?
- 如何使用productflavors和jni来设置Android库模块
- 用gradlew运行kotlin测试是抛出java.lang.SecurityException