[annot-reach] complete the set of android thread annotations

Summary:
Treat `MainThread` and `WorkerThread` annotations.

Fix wrong test (`AnyThread` cannot call a UI-only method, because it can be called by ANY thread ;) ) See https://developer.android.com/reference/android/support/annotation/AnyThread

Clean up the code a bit.

Reviewed By: jvillard

Differential Revision: D16183798

fbshipit-source-id: 6b7e3b27e
master
Nikos Gorogiannis 6 years ago committed by Facebook Github Bot
parent b4f3bce0c0
commit ffdc9193dc

@ -136,14 +136,18 @@ let buffer_overrun_u5 = from_string ~enabled:false "BUFFER_OVERRUN_U5"
let cannot_star = from_string "Cannot_star" let cannot_star = from_string "Cannot_star"
let checkers_allocates_memory = from_string "CHECKERS_ALLOCATES_MEMORY" let checkers_allocates_memory = from_string "CHECKERS_ALLOCATES_MEMORY" ~hum:"Allocates Memory"
let checkers_annotation_reachability_error = from_string "CHECKERS_ANNOTATION_REACHABILITY_ERROR" let checkers_annotation_reachability_error =
from_string "CHECKERS_ANNOTATION_REACHABILITY_ERROR" ~hum:"Annotation Reachability Error"
let checkers_calls_expensive_method =
from_string "CHECKERS_CALLS_EXPENSIVE_METHOD" ~hum:"Expensive Method Called"
let checkers_calls_expensive_method = from_string "CHECKERS_CALLS_EXPENSIVE_METHOD"
let checkers_expensive_overrides_unexpensive = let checkers_expensive_overrides_unexpensive =
from_string "CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED" from_string "CHECKERS_EXPENSIVE_OVERRIDES_UNANNOTATED" ~hum:"Expensive Overrides Unannotated"
let checkers_fragment_retain_view = let checkers_fragment_retain_view =

@ -252,14 +252,14 @@ module AnnotationSpec = struct
end end
module StandardAnnotationSpec = struct module StandardAnnotationSpec = struct
let from_annotations src_annots snk_annot = let from_annotations str_src_annots str_snk_annot =
let src_annots = List.map str_src_annots ~f:annotation_of_str in
let snk_annot = annotation_of_str str_snk_annot in
let has_annot ia = Annotations.ia_ends_with ia snk_annot.Annot.class_name in
let open AnnotationSpec in let open AnnotationSpec in
{ source_predicate= { source_predicate=
(fun tenv pname -> List.exists src_annots ~f:(fun a -> method_overrides_annot a tenv pname)) (fun tenv pname -> List.exists src_annots ~f:(fun a -> method_overrides_annot a tenv pname))
; sink_predicate= ; sink_predicate= (fun tenv pname -> check_attributes has_annot tenv pname)
(fun tenv pname ->
let has_annot ia = Annotations.ia_ends_with ia snk_annot.Annot.class_name in
check_attributes has_annot tenv pname )
; sanitizer_predicate= default_sanitizer ; sanitizer_predicate= default_sanitizer
; sink_annotation= snk_annot ; sink_annotation= snk_annot
; report= ; report=
@ -491,23 +491,22 @@ let parse_user_defined_specs = function
let annot_specs = let annot_specs =
let user_defined_specs =
parse_user_defined_specs Config.annotation_reachability_custom_pairs
|> List.map ~f:(fun (str_src_annots, str_snk_annot) ->
StandardAnnotationSpec.from_annotations str_src_annots str_snk_annot )
in
let open Annotations in
let cannot_call_ui_annots = [any_thread; for_non_ui_thread; worker_thread] in
let cannot_call_non_ui_annots = [any_thread; for_ui_thread; mainthread; ui_thread] in
[ (Language.Clang, CxxAnnotationSpecs.from_config ()) [ (Language.Clang, CxxAnnotationSpecs.from_config ())
; ( Language.Java ; ( Language.Java
, let user_defined_specs = , ExpensiveAnnotationSpec.spec :: NoAllocationAnnotationSpec.spec
let specs = parse_user_defined_specs Config.annotation_reachability_custom_pairs in :: StandardAnnotationSpec.from_annotations cannot_call_ui_annots ui_thread
List.map specs ~f:(fun (src_annots, snk_annot) -> :: StandardAnnotationSpec.from_annotations cannot_call_ui_annots mainthread
StandardAnnotationSpec.from_annotations :: StandardAnnotationSpec.from_annotations cannot_call_ui_annots for_ui_thread
(List.map ~f:annotation_of_str src_annots) :: StandardAnnotationSpec.from_annotations cannot_call_non_ui_annots worker_thread
(annotation_of_str snk_annot) ) :: StandardAnnotationSpec.from_annotations cannot_call_non_ui_annots for_non_ui_thread
in
ExpensiveAnnotationSpec.spec :: NoAllocationAnnotationSpec.spec
:: StandardAnnotationSpec.from_annotations
[ annotation_of_str Annotations.any_thread
; annotation_of_str Annotations.for_non_ui_thread ]
(annotation_of_str Annotations.ui_thread)
:: StandardAnnotationSpec.from_annotations
[annotation_of_str Annotations.ui_thread; annotation_of_str Annotations.for_ui_thread]
(annotation_of_str Annotations.for_non_ui_thread)
:: user_defined_specs ) ] :: user_defined_specs ) ]

@ -45,6 +45,8 @@ val mainthread : string
val ui_thread : string val ui_thread : string
val worker_thread : string
val visibleForTesting : string val visibleForTesting : string
val generated_graphql : string val generated_graphql : string

@ -7,7 +7,9 @@
package codetoanalyze.java.checkers; package codetoanalyze.java.checkers;
import android.support.annotation.MainThread;
import android.support.annotation.UiThread; import android.support.annotation.UiThread;
import android.support.annotation.WorkerThread;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
@ -30,6 +32,9 @@ public class UiThreads {
@UiThread @UiThread
void uiThread() {} void uiThread() {}
@MainThread
void mainThread() {}
@AnyThread @AnyThread
void anyThread() {} void anyThread() {}
@ -49,6 +54,16 @@ public class UiThreads {
forNonUiThread(); forNonUiThread();
} }
@MainThread
void callForNonUiThreadBad3() {
forNonUiThread();
}
@AnyThread
void callForNonUiThreadBad4() {
forNonUiThread();
}
@AnyThread @AnyThread
void callUiThreadBad1() { void callUiThreadBad1() {
uiThread(); uiThread();
@ -59,6 +74,11 @@ public class UiThreads {
uiThread(); uiThread();
} }
@WorkerThread
void callUiThreadBad3() {
uiThread();
}
@ForUiThread @ForUiThread
void callUiThreadOk() { void callUiThreadOk() {
uiThread(); uiThread();
@ -83,9 +103,4 @@ public class UiThreads {
void callAnyThreadOk3() { void callAnyThreadOk3() {
anyThread(); anyThread();
} }
@AnyThread
void callForNonUiThreadOk() {
forNonUiThread();
}
} }

@ -52,5 +52,8 @@ codetoanalyze/java/checkers/TwoCheckersExample.java, codetoanalyze.java.checkers
codetoanalyze/java/checkers/TwoCheckersExample.java, codetoanalyze.java.checkers.TwoCheckersExample.shouldRaisePerformanceCriticalError():java.util.List, 1, CHECKERS_CALLS_EXPENSIVE_METHOD, no_bucket, ERROR, [] codetoanalyze/java/checkers/TwoCheckersExample.java, codetoanalyze.java.checkers.TwoCheckersExample.shouldRaisePerformanceCriticalError():java.util.List, 1, CHECKERS_CALLS_EXPENSIVE_METHOD, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callForNonUiThreadBad1():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, [] codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callForNonUiThreadBad1():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callForNonUiThreadBad2():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, [] codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callForNonUiThreadBad2():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callForNonUiThreadBad3():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callForNonUiThreadBad4():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callUiThreadBad1():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, [] codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callUiThreadBad1():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callUiThreadBad2():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, [] codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callUiThreadBad2():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []
codetoanalyze/java/checkers/UiThreads.java, codetoanalyze.java.checkers.UiThreads.callUiThreadBad3():void, 1, CHECKERS_ANNOTATION_REACHABILITY_ERROR, no_bucket, ERROR, []

Loading…
Cancel
Save