首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >构造函数中注入次数的Lint规则

构造函数中注入次数的Lint规则
EN

Stack Overflow用户
提问于 2017-12-07 21:46:53
回答 2查看 689关注 0票数 1

我正试图在我的Android代码中创建一个Lint规则,以检查构造函数中的注入数,因此,如果我超过了视图模型的某个数字,我将提出一个lint警告。

我知道我必须在Lint检测器中实现一个UastScanner,但是我迷路了,因为我找不到好的文档。其他人做过这样的事吗?或者我在哪里能找到好的脱眼方法呢?

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-14 20:58:32

*备注-阅读编辑的解决方案的全部答案。*

我能够像这样编写UAST转换:

代码语言:javascript
复制
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()。以上客舱改为:

代码语言:javascript
复制
@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产生了预期的报告。

票数 2
EN

Stack Overflow用户

发布于 2017-12-14 17:37:53

因此,我能够使用JavaScanner找到解决方案,但还没有找到任何使用UastScanner的解决方案(这正是我想要使用的,因为我们也有Kotlin类):

代码语言:javascript
复制
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;
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47704372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档