2016-12-19 78 views
11

uygulayamadan bir sınıf araması bulursak, eğlenmek için özel bir tiftik detektörü yazıyorum. custom lint rule in Android (Java için aynı olmalıdır) oluşturma hakkında Big Nerd Ranches dersinden çıkıyorumJava/Android Report için Özel Lint, ara yüzünü

İstediğim olayı algılayabilirim. Sınıf kurucusu çağrıldı. Ancak, bir Abstract Syntax Tree aracılığıyla geçiş yaptığımızdan dolayı, geri bildirimin uygulanmasını tespit edemiyorum. Java'ya dosyayı kontrol etmek için nasıl söyleyeceğimi bilmiyorum ve sadece bir olay bulamadıysa rapor vereceğim. Bu durumda arayüz uygulaması. Her seferinde sadece bir yaprak görüyorum.

İki olayı nasıl ararım, her bir olayın gerçekleştiği yerleri depolar ve sonra mantığımı gerçekleştirir ve buna göre rapor veririm?

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; 
    } 

} 
+0

Sınıf kurucusu bazı fabrika yöntemlerine mi sarılacak? –

cevap

1

Eğer bir alan olarak bulmak ve tüm sözdizimi kastetmek sonunda bunları rapor referansları depolamak eğer Mümkün: Eğer yapıcı kullanımı için şimdi var gibi denetimi yapmak createJavaVisitor İçinde

. Bu noktada bir sorunu bildirmek yerine, CallBackDetector numaranızda, kurucunun kullanımına bir atıfta bulunacak bir koleksiyon alanı oluşturun. Daha sonra, tüm yapıcı kullanımlarının bir listesiyle sonlanacaksınız.

Şimdi de createJavaVisitor'un içinde, aradığınız arabirimi uygulayan herhangi bir sınıfı kontrol edin ve bunu başka bir alan koleksiyonuna ekleyin.

afterCheckProject (api here) yönteminin ne zaman biteceğini öğrenmek için Detector yöntemini geçersiz kılabilirsiniz. Bu yöntemde, iki koleksiyonunuz boyunca yineleyin ve eşleşen bir çift (koleksiyon ve uygulanan arayüz) olan her iki koleksiyondaki öğeleri kaldırın. Her iki koleksiyonda kalanlar Lint hatalarıdır ve bunları bu noktada sorun olarak ekleyebilirsiniz.