Sta*_*nd0 11 java android lint abstract-syntax-tree
我正在写一个定制的lint探测器,以获得乐趣.我将关于在Android中创建自定义lint规则的Big Nerd Ranches课程(对于Java应该是相同的)
我可以检测到我想要的事件.调用类构造函数.但是由于我们通过抽象语法树遍历这一事实, 我无法检测到回调的实现.我不知道如何告诉Java检查文件,只报告它是否找不到.在这种情况下,接口实现.因为我一次只看到一片叶子.
如何查找两次出现,存储每次发生的位置,然后执行我的逻辑并相应地报告?
package com.bignerdranch.linette.detectors;
import com.android.annotations.NonNull;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Context;
import com.android.tools.lint.detector.api.Detector;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.JavaContext;
import com.android.tools.lint.detector.api.Location;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.TextFormat;
import java.io.File;
import java.util.EnumSet;
import java.util.List;
import lombok.ast.AstVisitor;
import lombok.ast.Node;
/**
* Lint check for the usage of to-do statements
*/
public class CallBackDetector extends Detector implements Detector.JavaScanner {
private static final String FRAGMENT_MATCHER_STRING = "NoInternetDialogFragment()";
private static final String INTERFACE_MATCHER_STRING =
"NoInternetDialogFragment.NoInternetCallbackInterface";
private static final Class<? extends Detector> DETECTOR_CLASS = CallBackDetector.class;
private static final EnumSet<Scope> DETECTOR_SCOPE = Scope.JAVA_FILE_SCOPE;
private static final Implementation IMPLEMENTATION = new Implementation(
DETECTOR_CLASS,
DETECTOR_SCOPE
);
private static final String ISSUE_ID = "NoInternetDialogFragment";
private static final String ISSUE_DESCRIPTION =
"NoInternetDialogFragment Callback not detected";
private static final String ISSUE_EXPLANATION =
"When using NoInternetDialogFragment you must implement its' callback -- "
+ "NoInternetCallbackInterface";
private static final Category ISSUE_CATEGORY = Category.CORRECTNESS;
private static final int ISSUE_PRIORITY = 10;
private static final Severity ISSUE_SEVERITY = Severity.ERROR;
public static final Issue ISSUE = Issue.create(
ISSUE_ID,
ISSUE_DESCRIPTION,
ISSUE_EXPLANATION,
ISSUE_CATEGORY,
ISSUE_PRIORITY,
ISSUE_SEVERITY,
IMPLEMENTATION
);
/**
* Constructs a new {@link CallBackDetector} check
*/
public CallBackDetector() {
}
@Override
public boolean appliesTo(@NonNull Context context, @NonNull File file) {
return true;
}
@Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
return null;
}
@Override
public AstVisitor createJavaVisitor(@NonNull JavaContext context) {
String source = context.getContents();
// Check validity of source
if (source == null) {
return null;
}
if(source.indexOf(INTERFACE_MATCHER_STRING) >=0){
return null;
}
int index = source.indexOf(FRAGMENT_MATCHER_STRING);
for (int i = index; i >= 0; i = source.indexOf(FRAGMENT_MATCHER_STRING, i + 1)) {
Location location = Location.create(context.file, source, i,
i + FRAGMENT_MATCHER_STRING.length());
context.report(ISSUE, location, ISSUE.getBriefDescription(TextFormat.TEXT));
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您将找到的引用存储为字段并在所有语法遍历结束时报告它们,这是可能的:
在里面createJavaVisitor像现在一样检查构造函数的使用情况。此时不要报告问题,而是在您的文件中创建一个集合字段,CallBackDetector该字段将保存对构造函数的使用的引用。然后您将得到所有构造函数使用的列表。
现在还在内部createJavaVisitor检查是否有任何实现您正在搜索的接口的类,并将其添加到另一个字段集合中。
您可以重写您的方法afterCheckProject(此处为 api)Detector以了解其何时完成。在此方法中,迭代两个集合并从两个集合中删除匹配对(构造函数和正在实现的接口)的任何项目。任一集合中留下的任何内容都是 Lint 错误,此时您可以将它们添加为问题。
| 归档时间: |
|
| 查看次数: |
492 次 |
| 最近记录: |