2016-10-19 7 views
5

के लिए जाँच करने के लिए मैं निम्नलिखित एनोटेशन लिखा है:लेखन कस्टम फाहा चेतावनी कस्टम एनोटेशन

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 { 

} 

कौन सा करना है तरीकों जो समस्याएं पैदा कर सकता है, तो लापरवाही बुलाया टिप्पणी करने के लिए। मैंने अपनी परियोजना में एक एनोटेशन प्रोसेसर जोड़ा, लेकिन यह केवल javac कमांड के लॉग आउटपुट में चेतावनी प्रदान करता है। मैं इस चेतावनी के साथ एक विधि को कहीं भी अन्य चेतावनी चेतावनियों के साथ एंड्रॉइड स्टूडियो में दिखाना चाहता हूं। यही कारण है कि मैं एक कस्टम लिंट नियम लिखने की कोशिश कर रहा हूं। मैं फाहा शासन के बुनियादी कंकाल है:

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

} 

लेकिन मैं नहीं जानता कि कैसे यहां से आगे बढ़ने के लिए। मैं कैसे जांच सकता हूं कि किसी विधि पर कोई कथन मौजूद है या नहीं, और चेतावनी उठाएं कि यह एंड्रॉइड स्टूडियो में दिखाई देगी?

अद्यतन

यहाँ किसी के लिए भी मेरे डिटेक्टर वर्ग भी ऐसा ही करने के लिए देख रहा है:

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

    } 

} 

अद्यतन 2

आप एंड्रॉयड स्टूडियो निरीक्षण के साथ अपने कस्टम फाहा जांच एकीकृत कर सकते हैं अपनी प्रोजेक्ट की जड़ में lint.xml फ़ाइल बनाकर और आपको कस्टम लिंट नियम जोड़कर इस तरह:

<?xml version="1.0" encoding="UTF-8"?> 
<lint> 
    <issue id="Warning" severity="warning"/> 
</lint> 

नोटिस टैग की आईडी पर ध्यान दें आईडी को CaimitoDetector क्लास में Issue.create() विधि के पहले तर्क पर प्रदान की गई आईडी है। आपको इसे काम करने के लिए अपने/home/{user}/.android/lint फ़ोल्डर में अपने लिंट नियम को बनाकर आउटपुट की गई जार फ़ाइल को भी कॉपी करना होगा। मैंने इसके लिए एक कस्टम ग्रेडल कार्य लिखा था। यहाँ मेरी फाहा शासन के build.gradle फ़ाइल है

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) 

अद्यतन 3

तुम भी अद्यतन के रूप में एक ही प्रभाव प्राप्त करने के लिए अन्य परियोजनाओं पर निर्भरता के रूप में अपने जावा फाहा परियोजना में जोड़ सकते हैं 2.

enter image description here

अद्यतन 4

मैंने इस विषय पर https://medium.com/@mosesJay/writing-custom-lint-rules-and-integrating-them-with-android-studio-inspections-or-carefulnow-c54d72f00d30#.3hm576b4f पर एक ब्लॉग पोस्ट लिखा है।

उत्तर

2

लेकिन मैं कैसे यहाँ से

मैं अपने Detector पहले के लिए एक परीक्षण लिखने के लिए सुझाव है कि आगे बढ़ने के लिए पता नहीं है। यहां एक उदाहरण प्रोजेक्ट है जो दर्शाता है कि Detector परीक्षण कैसे लिखें [1]। इस तरह आप अपनी पसंद के अनुसार Detector को आजमा सकते हैं और समायोजित कर सकते हैं।

मैं एक annoation एक विधि

पर मौजूद है अगर मैं Android के डिफ़ॉल्ट [2] डिटेक्टरों पर एक नजर है करने के लिए सुझाव कैसे देख सकते हैं। वहां आपको शायद शुरू करने के लिए एक अच्छा बिंदु मिल जाएगा। जैसे AnnotationDetector

और एक चेतावनी उठाएं जैसे कि यह एंड्रॉइड स्टूडियो में दिखाई देगी?

यदि आप अपने प्रोजेक्ट में सही तरीके से अपने कस्टम नियमों को एकीकृत करते हैं, तो लिंट आपके लिए चेतावनी उठाएगी। अपनी परियोजना में कस्टम नियमों को एकीकृत करने के तरीके के बारे में विभिन्न विकल्पों के लिए कृपया यहां एक नज़र डालें [3]। नोट: कस्टम नियमों की AFAIK चेतावनियां केवल संबंधित ग्रैडल कार्य को चलाने पर ही सूचित की जाएंगी। एंड्रॉइड स्टूडियो का "ऑटो-हाइलाइट" कस्टम नियमों के साथ काम नहीं करता है।

  1. https://github.com/a11n/CustomLintRules
  2. https://android.googlesource.com/platform/tools/base/+/master/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks
  3. https://github.com/a11n/android-lint/tree/master/6_application
+0

करता lombok.ast पुस्तकालय किसी भी प्रलेखन मैं क्रम में उल्लेख कर सकते हैं बेहतर समझने के लिए क्या दूसरी कड़ी के स्रोत कोड में हो रहा है है? – Moses

+0

मुझे यह https://jar-download.com/java-documentation-javadoc.php?a=lombok-ast&g=com.android.tools.external.lombok&v=0.2.3 मिला, लेकिन वे अधिकतर खाली हैं, नहीं अत्यंत जानकारी। – Moses

+0

मुझे डर है कि यह सब आपको मिलेगा। अधिक एंड्रॉइड डिटेक्टर हैं जो लोम्बोक का उपयोग करते हैं और एनोटेशन के लिए खोज करते हैं (उदा। CallSuperDetector)। मुझे पता है कि यह परिष्कृत नहीं है, लेकिन मौजूदा समाधान लेते हुए, समझते हैं कि वे कैसे काम करते हैं और उनके दृष्टिकोण को अनुकूलित करते हैं, शायद हमारे पास है। यदि आपको और पता चलता है, तो कृपया मुझे बताएं :-) – a11n

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