denetlemek için: amaçlanmaktadırYazma özel tiftik uyarı Ben şu ek açıklama yazdım özel açıklama
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD})
public @interface Warning {
}
dikkatsizce denilen sorunlara neden olabilir yöntemlerini açıklama için. Projeme bir ek açıklama işlemci ekledim, ancak bu yalnızca javac komutunun günlük çıktısında uyarı veriyor. Bu uyarının çağrıldığı bir yöntemle, Android Studio'da bu uyarıyı diğer tiftik uyarılarıyla birlikte görünmesini istiyorum. Bu yüzden özel bir tiftik kuralı yazmaya çalışıyorum. Ben tiftik kuralının temel iskelete sahip:
import com.android.tools.lint.detector.api.Category;
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.Scope;
import com.android.tools.lint.detector.api.Severity;
public class CaimitoDetector extends Detector implements Detector.JavaScanner {
public static final Issue ISSUE = Issue.create(
"WarningAnnotation",
"This method has been annotated with @Warning",
"This method has special conditions surrounding it's use, be careful when using it and refer to its documentation.",
Category.USABILITY, 7, Severity.WARNING,
new Implementation(CaimitoDetector.class, Scope.JAVA_FILE_SCOPE));
@Override
public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {
}
}
import com.android.tools.lint.client.api.IssueRegistry;
import com.android.tools.lint.detector.api.Issue;
import java.util.Collections;
import java.util.List;
public class CaimitoIssueRegistry extends IssueRegistry {
@Override
public List<Issue> getIssues() {
return Collections.singletonList(CaimitoDetector.ISSUE);
}
}
Ama buradan devam etmek nasıl bilmiyorum. Bir yöntemde bir açıklama bulunup bulunmadığını nasıl kontrol edebilirim ve Android Studio'da görünecek şekilde bir uyarı yükseltebilir miyim? İşte
herkes için benim Dedektör sınıfı aynı şeyi arıyor
GÜNCELLEME:
import com.android.annotations.NonNull;
import com.android.tools.lint.client.api.JavaParser.ResolvedAnnotation;
import com.android.tools.lint.client.api.JavaParser.ResolvedMethod;
import com.android.tools.lint.client.api.JavaParser.ResolvedNode;
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.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.Speed;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.ast.AstVisitor;
import lombok.ast.ConstructorInvocation;
import lombok.ast.ForwardingAstVisitor;
import lombok.ast.MethodInvocation;
import lombok.ast.Node;
public class CaimitoAnnotationDetector extends Detector implements Detector.JavaScanner {
private static final String WARNING_ANNOTATION = "com.treemetrics.caimito.annotations.Warning";
public static final Issue ISSUE = Issue.create(
"Waqrning.",
"Be careful when using this method.",
"This method has special conditions surrounding it's use," +
" be careful when calling it and refer to its documentation.",
Category.USABILITY,
7,
Severity.WARNING,
new Implementation(
CaimitoAnnotationDetector.class,
Scope.JAVA_FILE_SCOPE));
@Override
public boolean appliesTo(@NonNull Context context, @NonNull File file) {
return true;
}
@NonNull
@Override
public Speed getSpeed() {
return Speed.FAST;
}
private static void checkMethodAnnotation(@NonNull JavaContext context,
@NonNull ResolvedMethod method,
@NonNull Node node,
@NonNull ResolvedAnnotation annotation) {
String signature = annotation.getSignature();
if(WARNING_ANNOTATION.equals(signature) || signature.endsWith(".Warning")) {
checkWarning(context, node, annotation);
}
}
private static void checkWarning(@NonNull JavaContext context,
@NonNull Node node,
@NonNull ResolvedAnnotation annotation) {
context.report(ISSUE, node, context.getLocation(node), "Warning");
}
// ---- Implements JavaScanner ----
@Override
public List<Class<? extends Node>> getApplicableNodeTypes() {
return Arrays.asList(
MethodInvocation.class,
ConstructorInvocation.class);
}
@Override
public AstVisitor createJavaVisitor(@NonNull JavaContext context) {
return new CallChecker(context);
}
private static class CallChecker extends ForwardingAstVisitor {
private final JavaContext mContext;
public CallChecker(JavaContext context) {
mContext = context;
}
@Override
public boolean visitMethodInvocation(@NonNull MethodInvocation call) {
ResolvedNode resolved = mContext.resolve(call);
if(resolved instanceof ResolvedMethod) {
ResolvedMethod method = (ResolvedMethod) resolved;
checkCall(call, method);
}
return false;
}
@Override
public boolean visitConstructorInvocation(@NonNull ConstructorInvocation call) {
ResolvedNode resolved = mContext.resolve(call);
if(resolved instanceof ResolvedMethod) {
ResolvedMethod method = (ResolvedMethod) resolved;
checkCall(call, method);
}
return false;
}
private void checkCall(@NonNull Node call, ResolvedMethod method) {
Iterable<ResolvedAnnotation> annotations = method.getAnnotations();
annotations = filterRelevantAnnotations(annotations);
for(ResolvedAnnotation annotation : annotations) {
checkMethodAnnotation(mContext, method, call, annotation);
}
}
private Iterable<ResolvedAnnotation> filterRelevantAnnotations(Iterable<ResolvedAnnotation> resolvedAnnotationsIn) {
List<ResolvedAnnotation> resolvedAnnotationsOut = new ArrayList<>();
for(ResolvedAnnotation resolvedAnnotation : resolvedAnnotationsIn) {
if(resolvedAnnotation.matches(WARNING_ANNOTATION)) {
resolvedAnnotationsOut.add(resolvedAnnotation);
}
}
return resolvedAnnotationsOut;
}
}
}
UPDATE 2
Android Studio denetimler ile özel tiftik kontrol entegre edebilirsiniz projenizin kökünde bir lint.xml dosyası oluşturarak ve bunun gibi size özel tiftik kuralı ekleyerek:
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="Warning" severity="warning"/>
</lint>
Sorun etiketinin kimliği, CaimitoDetector sınıfındaki Issue.create() yönteminin ilk bağımsız değişkeninde sağlanan kimliktir. Ayrıca, çalışmasını sağlamak için tiftik kuralınızı /home/{user}/.android/lint klasörünüze oluşturarak çıkarılan jar dosyasını da kopyalamanız gerekecektir. Bunun için özel bir taslak görevi yazdım. İşte benim tiftik kuralın build.gradle dosyasıdır
apply plugin: 'java'
targetCompatibility = '1.7'
sourceCompatibility = '1.7'
repositories {
jcenter()
}
dependencies {
compile 'com.android.tools.lint:lint-api:24.2.1'
compile 'com.android.tools.lint:lint-checks:24.2.1'
}
jar {
manifest {
attributes 'Manifest-Version': 1.0
attributes 'Lint-Registry': 'com.treemetrics.caimito.lint.CaimitoIssueRegistry'
}
}
defaultTasks 'assemble'
task copyLintJar(type: Copy) {
description = 'Copies the caimito-lint jar file into the {user.home}/.android/lint folder.'
from('build/libs/')
into(System.getProperty("user.home") + '/.android/lint')
include("*.jar")
}
// Runs the copyLintJar task after build has completed.
build.finalizedBy(copyLintJar)
Ayrıca güncelleme olarak aynı etkiyi elde etmek için diğer projeler üzerinde bir bağımlılık olarak Java tiftik proje ekleyebilir 3
GÜNCELLEME 2.
GÜNCELLEME 4
Bu konuya bir blog yazısı ekledim https://medium.com/@mosesJay/writing-custom-lint-rules-and-integrating-them-with-android-studio-inspections-or-carefulnow-c54d72f00d30#.3hm576b4f.
mu daha iyi, ikinci bağlantının kaynak kodunda ne olup bittiğini anlamak için başvurabilir herhangi bir belgeniz var lombok.ast kütüphane? – Moses
Bu https://jar-download.com/java-documentation-javadoc.php?a=lombok-ast&g=com.android.tools.external.lombok&v=0.2.3 adresini buldum, ancak çoğunlukla boşlar çok bilgi. – Moses
Korkarım ki alabileceğin her şey bu. Lombok kullanan ve ek açıklamaları arayabilen daha fazla Android dedektörü vardır (ör. CallSuperDetector). Bunun sofistike olmadığını biliyorum, ancak mevcut çözümleri ele alıp, onların nasıl çalıştığını ve adapte olduklarını anlamak belki de sahip olduğumuz her şeydir. Daha fazla bilgi ederseniz, lütfen bana bildirin :-) – a11n