2016-12-19 6 views
11

मैं मजेदार के लिए कस्टम लिंट डिटेक्टर लिख रहा हूं। मैं custom lint rule in Android (जावा के लिए समान होना चाहिए) बनाने पर बिग नेर्ड रांच सबक से बाहर जा रहा हूंजावा/एंड्रॉइड रिपोर्ट के लिए कस्टम लिंट अगर हमें अपने इंटरफेस को लागू किए बिना कक्षा कॉल मिलती है

मैं जिस घटना को चाहता हूं उसे पहचान सकता हूं। उस वर्ग निर्माता को बुलाया गया था। हालांकि इस तथ्य के कारण हम Abstract Syntax Tree के माध्यम से ट्रैवर्स कर रहे हैं, मैं कॉलबैक के कार्यान्वयन का पता लगाने में असफल रहा हूं। मुझे यकीन नहीं है कि फ़ाइल को जांचने के लिए जावा को कैसे बताना है और केवल रिपोर्ट करें कि क्या यह कोई घटना नहीं मिल सका। इस मामले में इंटरफ़ेस कार्यान्वयन। जैसा कि मैं एक समय में केवल एक पत्ता देख रहा हूँ।

मैं दो घटनाओं को कैसे देख सकता हूं, प्रत्येक घटना के स्थानों को संग्रहीत करता हूं और फिर अपना तर्क करता हूं और तदनुसार रिपोर्ट करता हूं?

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

क्या होगा यदि क्लास कन्स्ट्रक्टर कुछ फैक्ट्री विधि में लपेटा जाएगा? –

उत्तर

1

अगर आप संदर्भ है कि आप एक क्षेत्र के रूप में पाते हैं और उन सब को वाक्य रचना ट्रेवर्सल के अंत में रिपोर्ट की दुकान यह संभव है:

createJavaVisitor अंदर की तरह आप निर्माता के उपयोग के लिए अब जांच । इस बिंदु पर किसी समस्या की रिपोर्ट करने के बजाय आपके CallBackDetector में संग्रह फ़ील्ड बनाएं जो कि कन्स्ट्रक्टर के उपयोग के संदर्भ में होगा। फिर आप सभी कन्स्ट्रक्टर उपयोगों की एक सूची के साथ समाप्त हो जाएगा।

अब createJavaVisitor के अंदर भी इंटरफ़ेस को लागू करने वाले किसी भी वर्ग की जांच करें और इसे किसी अन्य फ़ील्ड संग्रह में जोड़ें।

आप अपने Detector में afterCheckProject (api here) विधि को ओवरराइड कर सकते हैं ताकि यह पता चल सके कि यह कब समाप्त हो गया है। इस विधि में, अपने दो संग्रहों के माध्यम से पुनरावृत्त करें और मिलान करने वाली जोड़ी (कन्स्ट्रक्टर और इंटरफ़ेस कार्यान्वित किया जा रहा है) दोनों संग्रहों से किसी भी आइटम को हटा दें। जो भी संग्रह में छोड़ा गया है वह आपकी लिंट त्रुटियां हैं, और आप उन्हें इस बिंदु पर मुद्दों के रूप में जोड़ सकते हैं।

संबंधित मुद्दे