[litho] Remove old domain

Summary: The new domain is much better than the old one. Let's kill the old one (along with old litho tests) and simplify things.

Reviewed By: skcho

Differential Revision: D18959627

fbshipit-source-id: df77ae20e
master
Ezgi Çiçek 5 years ago committed by Facebook Github Bot
parent e42bd8cd6c
commit 38421e2735

@ -160,7 +160,6 @@ DIRECT_TESTS += \
java_impurity \
java_inefficientKeysetIterator \
java_infer \
java_litho \
java_litho-required-props \
java_performance \
java_purity \

@ -1529,10 +1529,6 @@ INTERNAL OPTIONS
--never-returning-null json
Matcher or list of matchers for functions that never return null.
--new-litho-domain
Activates: [EXPERIMENTAL] Use new litho domain (Conversely:
--no-new-litho-domain)
--nullable-annotation-name string
Specify custom nullable annotation name

@ -1734,8 +1734,6 @@ and monitor_prop_size =
and nelseg = CLOpt.mk_bool ~deprecated:["nelseg"] ~long:"nelseg" "Use only nonempty lsegs"
and new_litho_domain = CLOpt.mk_bool ~long:"new-litho-domain" "[EXPERIMENTAL] Use new litho domain"
and nullable_annotation =
CLOpt.mk_string_opt ~long:"nullable-annotation-name" "Specify custom nullable annotation name"
@ -3013,8 +3011,6 @@ and monitor_prop_size = !monitor_prop_size
and nelseg = !nelseg
and new_litho_domain = !new_litho_domain
and nullable_annotation = !nullable_annotation
and nullsafe_optimistic_third_party_params_in_non_strict =

@ -490,8 +490,6 @@ val monitor_prop_size : bool
val nelseg : bool
val new_litho_domain : bool
val no_translate_libs : bool
val nullable_annotation : string option

@ -11,8 +11,6 @@ module F = Format
module LocalAccessPath = struct
type t = {access_path: AccessPath.t; parent: Typ.Procname.t} [@@deriving compare]
let equal = [%compare.equal: t]
let make access_path parent = {access_path; parent}
let make_from_access_expression ae parent =
@ -21,14 +19,6 @@ module LocalAccessPath = struct
let make_from_pvar pvar typ parent = make (AccessPath.of_pvar pvar typ) parent
let to_formal_option {access_path= ((_, base_typ) as base), accesses; parent} formal_map =
match FormalMap.get_formal_index base formal_map with
| Some formal_index ->
Some (make ((Var.of_formal_index formal_index, base_typ), accesses) parent)
| None ->
None
let pp fmt t = AccessPath.pp fmt t.access_path
end
@ -36,19 +26,6 @@ module LocalAccessPathSet = PrettyPrintable.MakePPSet (LocalAccessPath)
let suffixes = String.Set.of_list ["Attr"; "Dip"; "Px"; "Res"; "Sp"]
module MethodCall = struct
type t = {receiver: LocalAccessPath.t; procname: Typ.Procname.t; location: Location.t}
[@@deriving compare]
let make receiver procname location = {receiver; procname; location}
let pp fmt {receiver; procname} =
F.fprintf fmt "%a.%a" LocalAccessPath.pp receiver Typ.Procname.pp procname
let procname_to_string {procname} = Typ.Procname.get_method procname
end
module MethodCallPrefix = struct
type t =
{ (* TODO: We can remove the [receiver] field after we replace the old checker *)
@ -72,15 +49,8 @@ module MethodCallPrefix = struct
let procname_to_string {procname} = Typ.Procname.get_method procname
(* NOTE: This is only for sharing some code with the previous version of the checker. *)
let to_method_call {receiver; procname; location} = MethodCall.make receiver procname location
end
module CallSet = AbstractDomain.FiniteSet (MethodCall)
module OldDomain = AbstractDomain.Map (LocalAccessPath) (CallSet)
module NewDomain = struct
module CreatedLocation = struct
type t =
| ByCreateMethod of {location: Location.t; typ_name: Typ.name}
@ -96,8 +66,8 @@ module NewDomain = struct
module CreatedLocations = AbstractDomain.FiniteSet (CreatedLocation)
(** Map from access paths of callee parameters and return variable to caller's corresponding
access paths *)
(** Map from access paths of callee parameters and return variable to caller's corresponding access
paths *)
module SubstPathMap = struct
include PrettyPrintable.MakePPMonoMap (LocalAccessPath) (LocalAccessPath)
@ -138,8 +108,8 @@ module NewDomain = struct
append_one caller_return callee_return acc
| CreatedLocation.ByParameter path ->
let caller_path = SubstPathMap.find path map in
Option.value_map (find_opt caller_path caller) ~default:acc
~f:(fun caller_created -> append caller_return caller_created acc)
Option.value_map (find_opt caller_path caller) ~default:acc ~f:(fun caller_created ->
append caller_return caller_created acc )
in
CreatedLocations.fold accum_subst callee_returns acc )
end
@ -193,8 +163,7 @@ module NewDomain = struct
S.elements method_calls
let check_required_props ~check_on_string_set parent_typename ({is_checked; method_calls} as x)
=
let check_required_props ~check_on_string_set parent_typename ({is_checked; method_calls} as x) =
if not is_checked then (
let prop_set = to_string_set method_calls in
let call_chain = get_call_chain method_calls in
@ -303,8 +272,8 @@ module NewDomain = struct
Option.value_map (SubstPathMap.find_opt path map) ~default:acc ~f:(fun caller_path ->
Option.value_map (find_caller_created caller_path) ~default:acc
~f:(fun caller_created ->
merge_method_calls_on_substed ~callee_method_calls ~is_build_called
caller_created acc ) )
merge_method_calls_on_substed ~callee_method_calls ~is_build_called caller_created
acc ) )
in
let caller' = fold accum_substed callee empty in
merge (fun _ v v' -> match v' with Some _ -> v' | None -> v) caller caller'
@ -330,8 +299,12 @@ module NewDomain = struct
let widen ~prev ~next ~num_iters =
{ created= Created.widen ~prev:prev.created ~next:next.created ~num_iters
; method_called=
MethodCalled.widen ~prev:prev.method_called ~next:next.method_called ~num_iters }
; method_called= MethodCalled.widen ~prev:prev.method_called ~next:next.method_called ~num_iters
}
let contains_build {method_called} =
MethodCalled.exists (fun MethodCalled.Key.{is_build_called} _ -> is_build_called) method_called
let empty = {created= Created.empty; method_called= MethodCalled.empty}
@ -342,12 +315,11 @@ module NewDomain = struct
| Typ.{desc= Tptr (typ, _)} -> (
match Typ.name typ with
| Some typ_name
when PatternMatch.is_subtype_of_str tenv typ_name
"com.facebook.litho.Component$Builder" ->
when PatternMatch.is_subtype_of_str tenv typ_name "com.facebook.litho.Component$Builder"
->
let formal_ae = LocalAccessPath.make_from_pvar pvar ptr_typ pname in
let created_location = CreatedLocation.ByParameter formal_ae in
{ created=
Created.add formal_ae (CreatedLocations.singleton created_location) created
{ created= Created.add formal_ae (CreatedLocations.singleton created_location) created
; method_called=
MethodCalled.add
(MethodCalled.Key.no_build_called created_location)
@ -405,8 +377,7 @@ module NewDomain = struct
in
let map = SubstPathMap.make ~formals ~actuals ~caller_return ~callee_return in
let created =
Created.subst map ~caller_return ~callee_return ~caller:caller.created
~callee:callee.created
Created.subst map ~caller_return ~callee_return ~caller:caller.created ~callee:callee.created
in
let is_reachable =
let reachable_paths =
@ -461,9 +432,7 @@ module NewDomain = struct
let assign ~lhs ~rhs = map_no_return_called (Mem.assign ~lhs ~rhs)
let call_create lhs typ_name location =
map_no_return_called (Mem.call_create lhs typ_name location)
let call_create lhs typ_name location = map_no_return_called (Mem.call_create lhs typ_name location)
let call_builder ~ret ~receiver callee =
map_no_return_called (Mem.call_builder ~ret ~receiver callee)
@ -480,101 +449,10 @@ module NewDomain = struct
no_return_called=
Mem.subst ~formals ~actuals ~ret_id_typ ~caller_pname ~callee_pname
~caller:caller.no_return_called ~callee }
end
include struct
include AbstractDomain.Pair (OldDomain) (NewDomain)
let lift_old f (o, _) = f o
let map_old f (o, n) = (f o, n)
let map_new f (o, n) = (o, f n)
let init tenv pname formals = (OldDomain.empty, NewDomain.init tenv pname formals)
let add k v = map_old (OldDomain.add k v)
let remove k = map_old (OldDomain.remove k)
let bindings = lift_old OldDomain.bindings
let find k = lift_old (OldDomain.find k)
let mem k = lift_old (OldDomain.mem k)
let iter f = lift_old (OldDomain.iter f)
let assign ~lhs ~rhs = map_new (NewDomain.assign ~lhs ~rhs)
let call_create ret typ_name location = map_new (NewDomain.call_create ret typ_name location)
let call_builder ~ret ~receiver callee = map_new (NewDomain.call_builder ~ret ~receiver callee)
let call_build_method ~ret ~receiver = map_new (NewDomain.call_build_method ~ret ~receiver)
let call_return = map_new NewDomain.call_return
type summary = OldDomain.t * NewDomain.Mem.t
let pp_summary fmt (o, n) =
F.fprintf fmt "@[<v 2>@[Old:@;%a@]@,@[New:@;%a@]@]" OldDomain.pp o NewDomain.Mem.pp n
let get_summary ~is_void_func = map_new (NewDomain.get_summary ~is_void_func)
let check_required_props ~check_on_string_set =
map_new (NewDomain.Mem.check_required_props ~check_on_string_set)
end
let substitute ~(f_sub : LocalAccessPath.t -> LocalAccessPath.t option) old_astate =
OldDomain.fold
(fun original_access_path call_set acc ->
let access_path' =
match f_sub original_access_path with
| Some access_path ->
access_path
| None ->
original_access_path
in
let call_set' =
CallSet.fold
(fun ({procname; location} as call) call_set_acc ->
let receiver =
match f_sub call.receiver with Some receiver' -> receiver' | None -> call.receiver
in
CallSet.add {receiver; procname; location} call_set_acc )
call_set CallSet.empty
in
OldDomain.add access_path' call_set' acc )
old_astate OldDomain.empty
(** Unroll the domain to enumerate all the call chains ending in [call] and apply [f] to each
maximal chain. For example, if the domain encodes the chains foo().bar().goo() and foo().baz(),
[f] will be called once on foo().bar().goo() and once on foo().baz() *)
let iter_call_chains_with_suffix ~f call_suffix astate =
let rec unroll_call_ ({receiver; procname} as call : MethodCall.t) (acc, visited) =
let is_cycle (call : MethodCall.t) =
(* detect direct cycles and cycles due to mutual recursion *)
LocalAccessPath.equal call.receiver receiver || Typ.Procname.Set.mem call.procname visited
in
let acc' = call :: acc in
let visited' = Typ.Procname.Set.add procname visited in
try
let calls' = find receiver astate in
CallSet.iter
(fun call ->
if not (is_cycle call) then unroll_call_ call (acc', visited')
else f receiver.access_path acc' )
calls'
with Caml.Not_found -> f receiver.access_path acc'
in
unroll_call_ call_suffix ([], Typ.Procname.Set.empty)
type summary = Mem.t
let pp_summary fmt = F.fprintf fmt "@[<v 2>@[Litho Summary:@;%a@]@]" Mem.pp
let iter_call_chains ~f astate =
iter
(fun _ call_set ->
CallSet.iter (fun call -> iter_call_chains_with_suffix ~f call astate) call_set )
astate
let check_required_props ~check_on_string_set = Mem.check_required_props ~check_on_string_set

@ -6,7 +6,6 @@
*)
open! IStd
module F = Format
(** Access path + its parent procedure *)
module LocalAccessPath : sig
@ -15,41 +14,22 @@ module LocalAccessPath : sig
val make : AccessPath.t -> Typ.Procname.t -> t
val make_from_access_expression : HilExp.AccessExpression.t -> Typ.Procname.t -> t
val to_formal_option : t -> FormalMap.t -> t option
val pp : F.formatter -> t -> unit
end
val suffixes : String.Set.t
(** Called procedure & location + its receiver *)
module MethodCall : sig
type t = private {receiver: LocalAccessPath.t; procname: Typ.Procname.t; location: Location.t}
[@@deriving compare]
val make : LocalAccessPath.t -> Typ.Procname.t -> Location.t -> t
val pp : F.formatter -> t -> unit
val procname_to_string : t -> string
end
module MethodCallPrefix : sig
type t
type t = private
{receiver: LocalAccessPath.t; prefix: string; procname: Typ.Procname.t; location: Location.t}
val make : LocalAccessPath.t -> Typ.Procname.t -> Location.t -> t
val to_method_call : t -> MethodCall.t
end
module CallSet : module type of AbstractDomain.FiniteSet (MethodCall)
module OldDomain : module type of AbstractDomain.Map (LocalAccessPath) (CallSet)
module NewDomain : sig
module Mem : sig
type t
val contains_build : t -> bool
end
include AbstractDomain.S
@ -63,25 +43,12 @@ module NewDomain : sig
-> caller:t
-> callee:Mem.t
-> t
end
include module type of AbstractDomain.Pair (OldDomain) (NewDomain)
(** type for saving in summary payload *)
type summary = OldDomain.t * NewDomain.Mem.t
type summary = Mem.t
val init : Tenv.t -> Typ.Procname.t -> (Pvar.t * Typ.t) list -> t
val add : LocalAccessPath.t -> CallSet.t -> t -> t
val remove : LocalAccessPath.t -> t -> t
val mem : LocalAccessPath.t -> t -> bool
val find : LocalAccessPath.t -> t -> CallSet.t
val bindings : summary -> (LocalAccessPath.t * CallSet.t) list
val assign : lhs:LocalAccessPath.t -> rhs:LocalAccessPath.t -> t -> t
val call_create : LocalAccessPath.t -> Typ.name -> Location.t -> t -> t
@ -105,10 +72,3 @@ val check_required_props :
check_on_string_set:(Typ.name -> MethodCallPrefix.t list -> String.Set.t -> unit)
-> summary
-> summary
val substitute : f_sub:(LocalAccessPath.t -> LocalAccessPath.t option) -> OldDomain.t -> OldDomain.t
(** Substitute each access path in the domain using [f_sub]. If [f_sub] returns None, the original
access path is retained; otherwise, the new one is used *)
val iter_call_chains : f:(AccessPath.t -> MethodCall.t list -> unit) -> summary -> unit
(** Apply [f] to each maximal call chain encoded in [t] *)

@ -100,32 +100,11 @@ struct
type nonrec extras = extras
let apply_callee_summary summary_opt ~caller_pname ~callee_pname ret_id_typ formals actuals
((old_domain, new_domain) as astate) =
Option.value_map summary_opt ~default:astate ~f:(fun (old_callee, new_callee) ->
(* TODO: append paths if the footprint access path is an actual path instead of a var *)
let f_sub {Domain.LocalAccessPath.access_path= (var, _), _} =
match Var.get_footprint_index var with
| Some footprint_index -> (
match List.nth actuals footprint_index with
| Some (HilExp.AccessExpression actual_access_expr) ->
Some
(Domain.LocalAccessPath.make
(HilExp.AccessExpression.to_access_path actual_access_expr)
caller_pname)
| _ ->
None )
| None ->
if Var.is_return var then
Some (Domain.LocalAccessPath.make (ret_id_typ, []) caller_pname)
else None
in
let astate_old = Domain.substitute ~f_sub old_callee |> Domain.OldDomain.join old_domain in
let astate_new =
Domain.NewDomain.subst ~formals ~actuals ~ret_id_typ ~caller_pname ~callee_pname
~caller:new_domain ~callee:new_callee
in
(astate_old, astate_new) )
let apply_callee_summary summary_opt ~caller_pname ~callee_pname ret_id_typ formals actuals astate
=
Option.value_map summary_opt ~default:astate ~f:(fun callee_summary ->
Domain.subst ~formals ~actuals ~ret_id_typ ~caller_pname ~callee_pname ~caller:astate
~callee:callee_summary )
let exec_instr astate ProcData.{summary; tenv; extras= {get_proc_summary_and_formals}} _
@ -144,19 +123,11 @@ struct
Domain.LocalAccessPath.make_from_access_expression receiver_ae caller_pname
in
if
( LithoContext.check_callee ~callee_pname ~tenv callee_summary_opt
|| (* track callee in order to report respective errors *)
Domain.mem receiver astate
(* track anything called on a receiver we're already tracking *) )
LithoContext.check_callee ~callee_pname ~tenv callee_summary_opt
(* track callee in order to report respective errors *)
&& LithoContext.satisfies_heuristic ~callee_pname ~callee_summary_opt tenv
then
let return_access_path = Domain.LocalAccessPath.make (return_base, []) caller_pname in
let callee = Domain.MethodCall.make receiver callee_pname location in
let return_calls =
(try Domain.find return_access_path astate with Caml.Not_found -> Domain.CallSet.empty)
|> Domain.CallSet.add callee
in
let astate = Domain.add return_access_path return_calls astate in
match get_component_create_typ_opt callee_pname tenv with
| Some create_typ ->
Domain.call_create return_access_path create_typ location astate
@ -195,12 +166,6 @@ struct
(HilExp.AccessExpression.to_access_path rhs_ae)
caller_pname
in
let astate =
try
let call_set = Domain.find rhs_access_path astate in
Domain.remove rhs_access_path astate |> Domain.add lhs_access_path call_set
with Caml.Not_found -> astate
in
Domain.assign ~lhs:lhs_access_path ~rhs:rhs_access_path astate
| _ ->
astate
@ -242,12 +207,7 @@ module MakeAnalyzer (LithoContext : LithoContext with type summary = Domain.summ
if LithoContext.should_report proc_desc tenv then LithoContext.report post tenv summary
else post
in
let postprocess (old_astate, new_astate) formal_map : Domain.summary =
let f_sub access_path = Domain.LocalAccessPath.to_formal_option access_path formal_map in
(Domain.substitute ~f_sub old_astate, new_astate)
in
let payload = postprocess post (FormalMap.make proc_desc) in
TF.Payload.update_summary payload summary
TF.Payload.update_summary post summary
| None ->
summary
end

@ -72,26 +72,13 @@ let report_missing_required_prop summary prop parent_typename loc call_chain =
in
let ltr =
Errlog.make_trace_element 0 loc message []
:: List.map call_chain ~f:(fun Domain.MethodCall.{procname; location} ->
:: List.map call_chain ~f:(fun Domain.MethodCallPrefix.{procname; location} ->
let call_msg = F.asprintf "calls %a" Typ.Procname.pp procname in
Errlog.make_trace_element 0 location call_msg [] )
in
Reporting.log_error summary ~loc ~ltr IssueType.missing_required_prop message
(* walk backward through [call_chain] and return the first type T <: Component that is not part of
the Litho framework (i.e., is client code) *)
let find_client_component_type call_chain =
List.find_map
~f:(fun Domain.MethodCall.{procname} ->
match procname with
| Typ.Procname.Java java_pname ->
Typ.Name.Java.get_outer_class (Typ.Procname.Java.get_class_type_name java_pname)
| _ ->
None )
call_chain
let has_prop prop_set prop =
let check prop =
String.Set.mem prop_set prop
@ -124,19 +111,13 @@ module LithoContext = struct
let satisfies_heuristic ~callee_pname ~callee_summary_opt tenv =
(* If the method is build() or create() itself or doesn't contain a build() in
its summary, we want to track it in the domain. *)
let build_exists_in_callees =
Option.value_map ~default:false callee_summary_opt ~f:(fun sum ->
LithoDomain.Mem.contains_build sum )
in
LithoFramework.is_component_build_method callee_pname tenv
|| LithoFramework.is_component_create_method callee_pname tenv
||
(* check if build()/create() exists in callees *)
let build_exists_in_callees =
Option.value_map callee_summary_opt ~default:[] ~f:Domain.bindings
|> List.exists ~f:(fun (_, call_set) ->
LithoDomain.CallSet.exists
(fun LithoDomain.MethodCall.{procname} ->
LithoFramework.is_component_build_method procname tenv
|| LithoFramework.is_component_create_method procname tenv )
call_set )
in
match callee_pname with
| Typ.Procname.Java java_callee_procname ->
not (Typ.Procname.Java.is_static java_callee_procname || build_exists_in_callees)
@ -153,49 +134,15 @@ module LithoContext = struct
&& Procdesc.get_access proc_desc <> PredSymb.Private
let check_on_string_set tenv summary parent_typename call_chain prop_set =
let report astate tenv summary =
let check_on_string_set parent_typename call_chain prop_set =
let required_props = get_required_props parent_typename tenv in
List.iter required_props ~f:(fun required_prop ->
if not (has_prop prop_set required_prop) then
report_missing_required_prop summary required_prop parent_typename
(Summary.get_loc summary) call_chain )
let check_on_string_set_prefix tenv summary parent_typename call_chain_prefix prop_set =
let call_chain = List.map call_chain_prefix ~f:Domain.MethodCallPrefix.to_method_call in
check_on_string_set tenv summary parent_typename call_chain prop_set
let report astate tenv summary =
let check_required_prop_chain _ call_chain =
let call_chain =
List.drop_while call_chain ~f:(fun Domain.MethodCall.{procname} ->
not (LithoFramework.is_component_create_method procname tenv) )
in
let rev_chain = List.rev call_chain in
match rev_chain with
| Domain.MethodCall.{procname} :: _
when LithoFramework.is_component_build_method procname tenv -> (
(* Here, we'll have a type name like MyComponent$Builder in hand. Truncate the $Builder
part from the typename, then look at the fields of MyComponent to figure out which
ones are annotated with @Prop *)
match find_client_component_type call_chain with
| Some parent_typename ->
let prop_set =
List.map ~f:Domain.MethodCall.procname_to_string call_chain |> String.Set.of_list
in
check_on_string_set tenv summary parent_typename call_chain prop_set
| _ ->
() )
| _ ->
()
in
if Config.new_litho_domain then
let check_on_string_set_prefix = check_on_string_set_prefix tenv summary in
Domain.check_required_props ~check_on_string_set:check_on_string_set_prefix astate
else (
Domain.iter_call_chains ~f:check_required_prop_chain astate ;
astate )
Domain.check_required_props ~check_on_string_set astate
let session_name = "litho required props"

@ -5,7 +5,7 @@
TESTS_DIR = ../../..
INFER_OPTIONS = --litho-required-props-only --new-litho-domain --debug-exceptions
INFER_OPTIONS = --litho-required-props-only --debug-exceptions
INFERPRINT_OPTIONS = --issues-tests
SOURCES = $(wildcard *.java)

@ -1,50 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.litho;
public class Column extends Component {
static native Builder acquire();
public static Builder create() {
Builder builder = acquire();
if (builder == null) {
builder = new Builder();
}
return builder;
}
public static class Builder extends Component.Builder {
public Builder child(Component child) {
if (child == null) {
return this;
}
return this;
}
public Builder child(Component.Builder child) {
if (child == null) {
return this;
}
return child(child.build());
}
Column mColumn;
@Override
public Column build() {
return mColumn;
}
@Override
public Builder getThis() {
return this;
}
}
}

@ -1,22 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.litho;
public class Component {
public abstract static class Builder<T extends Builder<T>> {
public abstract Component build();
public abstract T getThis();
public T commonProp(Object prop) {
return getThis();
}
}
}

@ -1,12 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
TESTS_DIR = ../../..
INFER_OPTIONS = --litho-required-props-only --debug-exceptions
INFERPRINT_OPTIONS = --issues-tests
SOURCES = $(wildcard *.java)
include $(TESTS_DIR)/javac.make

@ -1,54 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.litho;
import com.facebook.litho.Component;
import com.facebook.litho.annotations.Prop;
public class MyComponent extends Component {
@Prop Object prop1; // implicitly non-optional
@Prop(optional = true)
Object prop2; // explicitly optional
@Prop(optional = false)
Object prop3; // explicitly non-optional
Object nonProp;
public Builder create() {
return new Builder();
}
public static class Builder extends Component.Builder<Builder> {
MyComponent mMyComponent;
public Builder prop1(Object o) {
this.mMyComponent.prop1 = o;
return this;
}
public Builder prop2(Object o) {
this.mMyComponent.prop2 = o;
return this;
}
public Builder prop3(Object o) {
this.mMyComponent.prop3 = o;
return this;
}
public MyComponent build() {
return mMyComponent;
}
@Override
public Builder getThis() {
return this;
}
}
}

@ -1,43 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.litho;
import com.facebook.litho.annotations.Prop;
public class MyLithoComponent extends Component {
@Prop Object prop1; // implicitly non-optional
@Prop(optional = false)
Object prop2; // explicitly non-optional
public Builder create() {
return new Builder();
}
public static class Builder extends Component.Builder<Builder> {
MyLithoComponent mMyLithoComponent;
public Builder prop1(Object o) {
this.mMyLithoComponent.prop1 = o;
return this;
}
public Builder prop2(Object o) {
this.mMyLithoComponent.prop2 = o;
return this;
}
public MyLithoComponent build() {
return mMyLithoComponent;
}
@Override
public Builder getThis() {
return this;
}
}
}

@ -1,38 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.litho;
import com.facebook.litho.Component;
import com.facebook.litho.annotations.TreeProp;
class MyTreeComponent extends Component {
@TreeProp Object prop1; // implicitly non-optional
Object nonProp;
public Builder create() {
return new Builder();
}
static class Builder extends Component.Builder<Builder> {
MyTreeComponent mMyTreeComponent;
public Builder prop1(Object o) {
this.mMyTreeComponent.prop1 = o;
return this;
}
public MyTreeComponent build() {
return mMyTreeComponent;
}
@Override
public Builder getThis() {
return this;
}
}
}

@ -1,22 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.litho.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Prop {
ResType resType() default ResType.NONE;
boolean optional() default false;
String varArg() default "";
}

@ -1,418 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.litho;
import com.facebook.litho.Column;
import com.facebook.litho.Component;
import com.facebook.litho.MyLithoComponent;
import java.util.ArrayList;
public class RequiredProps {
public MyComponent mMyComponent;
public MyLithoComponent mMyLithoComponent;
public ResPropComponent mResPropComponent;
public VarArgPropComponent mVarArgPropComponent;
public Component buildWithAllOk() {
return mMyComponent
.create()
.prop1(new Object())
.prop2(new Object())
.prop3(new Object())
.build();
}
// prop 2 is optional
public Component buildWithout2Ok() {
return mMyComponent.create().prop1(new Object()).prop3(new Object()).build();
}
// prop 1 is required
public Component buildWithout1Bad() {
return mMyComponent.create().prop2(new Object()).prop3(new Object()).build();
}
// prop3 is required
public Component buildWithout3Bad() {
return mMyComponent.create().prop1(new Object()).prop2(new Object()).build();
}
public Component buildWithCommonPropOk() {
return mMyComponent
.create()
.prop1(new Object())
.commonProp(new Object())
.prop3(new Object())
.build();
}
private static MyComponent.Builder setProp1(MyComponent.Builder builder) {
return builder.prop1(new Object());
}
private static MyComponent.Builder setProp3(MyComponent.Builder builder) {
return builder.prop3(new Object());
}
public Component setProp1InCalleeOk() {
return setProp1(mMyComponent.create().prop2(new Object())).prop3(new Object()).build();
}
public Component setProp3InCalleeOk() {
return setProp3(mMyComponent.create().prop1(new Object()).prop2(new Object())).build();
}
public Component setProp3InCalleeButForgetProp1Bad() {
return setProp3(mMyComponent.create()).prop2(new Object()).build();
}
public Component setRequiredOnOneBranchBad(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder = builder.prop1(new Object());
}
return builder.prop2(new Object()).prop3(new Object()).build();
}
public Component setRequiredOnBothBranchesOk(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder = builder.prop1(new Object());
} else {
builder = builder.prop1(new Object());
}
return builder.prop2(new Object()).prop3(new Object()).build();
}
// current domain can't handle implicit calls like this
public Component setRequiredOnBothBranchesNoAssignOk_FP(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder.prop1(new Object());
} else {
builder.prop1(new Object());
}
return builder.prop2(new Object()).prop3(new Object()).build();
}
// gets confused at cyclic dependency to builder when setting prop1
public Component setRequiredOk(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
builder = builder.prop1(new Object());
return builder.prop2(new Object()).prop3(new Object()).build();
}
// gets confused at side-effectfull prop setting
public Component setRequiredEffectful_FP(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
builder.prop1(new Object());
return builder.prop2(new Object()).prop3(new Object()).build();
}
public Component setRequiredOnOneBranchEffectfulBad(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder.prop1(new Object());
}
return builder.prop2(new Object()).prop3(new Object()).build();
}
public void buildPropLithoMissingOneInLoopBad(int x) {
for (int i = 0; i < x; i++) {
Column.create()
.child(mMyLithoComponent.create().prop1(new Object()).commonProp(new Object()))
.build();
}
}
// due to mutual recursion check, we break cycle at seen props
public Component doubleSetMissingBad_FN() {
Component.Builder builder =
mMyComponent.create().commonProp(new Object()).prop3(new Object()).commonProp(new Object());
return builder.build();
}
// due to mutual recursion check, we break cycle at seen props
public Component doubleSetCommonOk() {
Component.Builder builder =
mMyComponent
.create()
.prop1(new Object())
.commonProp(new Object())
.prop3(new Object())
.commonProp(new Object());
return builder.build();
}
// only missing prop3
public Component setRequiredOnBothBranchesMissingProp3Bad(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder.prop1(new Object());
} else {
builder.prop1(new Object());
}
return builder.prop2(new Object()).build();
}
public void buildPropInConditionalOk_FP(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder.prop1(new Object()).prop3(new Object());
} else {
builder.prop1(new Object()).prop3(new Object());
}
builder.build();
}
// should be only missing prop3
public void buildPropMissingInConditionalBad(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder.prop1(new Object()).prop3(new Object());
} else {
builder.prop2(new Object()).prop1(new Object());
}
builder.build();
}
public boolean isEmptyOrNull(String str) {
return str == null || str.isEmpty();
}
public void buildInterProcUnrelatedBad(boolean b, String s) {
MyComponent.Builder builder = mMyComponent.create().prop1(new Object());
if (!isEmptyOrNull(s)) {
builder.prop3(new Object());
}
builder.build();
}
// don't want to report here; want to report at clients that don't pass prop1
private MyComponent buildSuffix(MyComponent.Builder builder) {
return builder.prop2(new Object()).prop3(new Object()).build();
}
// shouldn't report here; prop 1 passed
public Component callBuildSuffixWithRequiredOk() {
return buildSuffix(mMyComponent.create().prop1(new Object()));
}
// should report here; forgot prop 1
public Component callBuildSuffixWithoutRequiredBad() {
return buildSuffix(mMyComponent.create());
}
public Object generalTypeWithout2Ok() {
Component.Builder builder = mMyComponent.create().prop1(new Object()).prop3(new Object());
return builder.build();
}
public Object generalTypeForgot3Bad() {
MyComponent.Builder builder1 = mMyComponent.create();
Component.Builder builder2 = (Component.Builder) builder1.prop1(new Object());
// don't fail to find required @Prop's for MyComponent.Builder even though the static type that
// build is invoked on is [builder2]
return builder2.build();
}
public void buildWithColumnChildBad() {
Column.Builder builder = Column.create();
Component.Builder childBuilder = mMyComponent.create().prop1(new Object());
// forgot prop 3, and builder.child() will invoke build() on childBuilder
builder.child(childBuilder);
}
public Component buildWithColumnChildOk() {
return Column.create()
.child(mMyComponent.create().prop1(new Object()).prop3(new Object()))
.build();
}
public void buildPropResWithNormalOk() {
mResPropComponent.create().prop(new Object()).build();
}
public void buildPropResWithResOk() {
mResPropComponent.create().propRes(new Object()).build();
}
public void buildPropResWithAttrOk() {
mResPropComponent.create().propAttr(new Object()).build();
}
public void buildPropResWithDipOk() {
mResPropComponent.create().propDip(new Object()).build();
}
public void buildPropResWithPxOk() {
mResPropComponent.create().propPx(new Object()).build();
}
public void buildPropResWithSpOk() {
mResPropComponent.create().propSp(new Object()).build();
}
public void buildPropResMissingBad() {
mResPropComponent.create().build();
}
public void buildPropResInCondOk_FP(boolean b) {
ResPropComponent.Builder builder = mResPropComponent.create();
if (b) {
builder.propAttr(new Object());
} else {
builder.propDip(new Object());
}
builder.build();
}
public void buildPropResInCondOneNormalOk_FP(boolean b) {
ResPropComponent.Builder builder = mResPropComponent.create();
if (b) {
builder.propAttr(new Object());
} else {
builder.prop(new Object());
}
builder.build();
}
public void buildPropVarArgNormalOk() {
mVarArgPropComponent.create().props(new ArrayList<Object>()).build();
}
public void buildPropVarArgElementOk() {
mVarArgPropComponent.create().prop(new Object()).build();
}
public void buildPropVarArgAttrElementOk() {
mVarArgPropComponent.create().propAttr(new Object()).build();
}
public void buildPropVarArgNormalAttrElementOk() {
mVarArgPropComponent.create().propsAttr(new ArrayList<Object>()).build();
}
public void buildPropVarArgMissingBad() {
mVarArgPropComponent.create().build();
}
public Component buildPropLithoMissingBothBad() {
return mMyLithoComponent.create().build();
}
public void buildPropLithoMissingOneBad() {
Column.create()
.child(mMyLithoComponent.create().prop1(new Object()).commonProp(new Object()))
.build();
}
public Component buildPropLithoOK() {
Component.Builder layoutBuilder =
mMyLithoComponent.create().prop1(new Object()).prop2(new Object());
return layoutBuilder.build();
}
public void castImpossibleOk_FP(Object o1) {
Component.Builder builder = mMyLithoComponent.create();
if (builder instanceof MyComponent.Builder)
((MyComponent.Builder) builder)
.build(); // this branch will never be taken but we can't detect it yet
}
void castOk(Object o1) {
Component.Builder builder = mMyLithoComponent.create().prop1(new Object()).prop2(new Object());
if (builder instanceof MyLithoComponent.Builder)
((MyLithoComponent.Builder) builder).build(); // this branch will be taken
}
Component.Builder createBuilder() {
return mMyLithoComponent.create();
}
void castMissingOneBad(Object o1) {
Component.Builder builder = createBuilder();
if (builder instanceof MyLithoComponent.Builder)
((MyLithoComponent.Builder) builder).prop2(new Object()).build(); // this branch will be taken
}
void buildMissingProp3_FN() {
Component.Builder builder = mMyComponent.create();
((MyLithoComponent.Builder) builder).prop1(new Object()).prop2(new Object()).build();
}
public class NonRequiredTreeProps {
public MyTreeComponent mMyTreeComponent;
public MyTreeComponent buildWithoutOk() {
return mMyTreeComponent.create().build();
}
}
public Component buildPropLithoMissingInOneBranchBad(boolean b) {
if (b) {
return mMyLithoComponent.create().prop1(new Object()).build();
} else {
return mMyLithoComponent.create().prop1(new Object()).prop2(new Object()).build();
}
}
public Component buildPropLithoMissingInOneBranchBeforeBuildBad(boolean b) {
MyLithoComponent.Builder builder =
b
? mMyLithoComponent.create().prop1(new Object())
: mMyLithoComponent.create().prop1(new Object()).prop2(new Object());
return builder.build();
}
public Component setRequiredOnOneBothBranchesWithCreateOk_FP(boolean b) {
MyComponent.Builder builder = mMyComponent.create();
if (b) {
builder.prop1(new Object());
} else {
builder = mMyComponent.create().prop1(new Object());
}
return builder.prop2(new Object()).prop3(new Object()).build();
}
public Component missingProp3InOneBranchBeforeBuildBad(boolean b) {
Component.Builder builder =
b
? mMyComponent.create().prop1(new Object())
: mMyLithoComponent.create().prop1(new Object()).prop2(new Object());
return builder.build();
}
public Component missingProp2InOneBranchBeforeBuildBad(boolean b) {
Component.Builder builder =
b
? mMyComponent.create().prop1(new Object()).prop3(new Object())
: mMyLithoComponent.create().prop1(new Object());
return builder.build();
}
public Component missingProp1InBothBranchesBeforeBuildBad(boolean b) {
Component.Builder builder =
b
? mMyComponent.create().prop3(new Object())
: mMyLithoComponent.create().prop2(new Object());
return builder.build();
}
public Component createDiffferentInBranchesBeforeBuildOk(boolean b) {
Component.Builder builder =
b
? mMyComponent.create().prop1(new Object()).prop3(new Object())
: mMyLithoComponent.create().prop1(new Object()).prop2(new Object());
return builder.build();
}
}

@ -1,69 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.litho;
import com.facebook.litho.Component;
import com.facebook.litho.annotations.Prop;
import com.facebook.litho.annotations.ResType;
/**
* using @Prop(resType = ..) allows you to set the Prop with any of .propname, .propnameRes, or
* .propnameAttr
*/
public class ResPropComponent extends Component {
@Prop(resType = ResType.SOME)
Object prop; // implicitly non-optional with resType
public Builder create() {
return new Builder();
}
public static class Builder extends Component.Builder<Builder> {
ResPropComponent mResPropComponent;
public Builder prop(Object o) {
this.mResPropComponent.prop = o;
return this;
}
public Builder propRes(Object o) {
this.mResPropComponent.prop = o;
return this;
}
public Builder propAttr(Object o) {
this.mResPropComponent.prop = o;
return this;
}
public Builder propDip(Object o) {
this.mResPropComponent.prop = o;
return this;
}
public Builder propPx(Object o) {
this.mResPropComponent.prop = o;
return this;
}
public Builder propSp(Object o) {
this.mResPropComponent.prop = o;
return this;
}
public ResPropComponent build() {
return mResPropComponent;
}
@Override
public Builder getThis() {
return this;
}
}
}

@ -1,12 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.litho.annotations;
public enum ResType {
SOME,
NONE
}

@ -1,20 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.litho.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface TreeProp {
ResType resType() default ResType.NONE;
boolean optional() default false;
}

@ -1,83 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package codetoanalyze.java.litho;
import com.facebook.litho.Component;
import com.facebook.litho.annotations.Prop;
import java.util.ArrayList;
import java.util.List;
/** varArg test */
class VarArgPropComponent extends Component {
@Prop(varArg = "prop")
List<Object> props;
public Builder create() {
return new Builder();
}
static class Builder extends Component.Builder<Builder> {
VarArgPropComponent mVarArgPropComponent;
public Builder prop(Object prop) {
if (prop == null) {
return this;
}
if (this.mVarArgPropComponent.props == null) {
this.mVarArgPropComponent.props = new ArrayList<Object>();
}
this.mVarArgPropComponent.props.add(prop);
return this;
}
public Builder propAttr(Object prop) {
if (prop == null) {
return this;
}
if (this.mVarArgPropComponent.props == null) {
this.mVarArgPropComponent.props = new ArrayList<Object>();
}
this.mVarArgPropComponent.props.add(prop);
return this;
}
public Builder propsAttr(List<Object> props) {
if (props == null) {
return this;
}
if (this.mVarArgPropComponent.props == null || this.mVarArgPropComponent.props.isEmpty()) {
this.mVarArgPropComponent.props = props;
} else {
this.mVarArgPropComponent.props.addAll(props);
}
return this;
}
public Builder props(List<Object> props) {
if (props == null) {
return this;
}
if (this.mVarArgPropComponent.props == null || this.mVarArgPropComponent.props.isEmpty()) {
this.mVarArgPropComponent.props = props;
} else {
this.mVarArgPropComponent.props.addAll(props);
}
return this;
}
public VarArgPropComponent build() {
return mVarArgPropComponent;
}
@Override
public Builder getThis() {
return this;
}
}
}

@ -1,35 +0,0 @@
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildInterProcUnrelatedBad(boolean,java.lang.String):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop1(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropInConditionalOk_FP(boolean):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropInConditionalOk_FP(boolean):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropLithoMissingBothBad():com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop2 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropLithoMissingBothBad():com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropLithoMissingInOneBranchBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop2 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop1(Object),calls MyLithoComponent MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropLithoMissingInOneBranchBeforeBuildBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop2 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop1(Object),calls MyLithoComponent MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropLithoMissingOneBad():void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop2 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop1(Object),calls Component$Builder Component$Builder.commonProp(Object),calls Component Component$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropLithoMissingOneInLoopBad(int):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop2 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop1(Object),calls Component$Builder Component$Builder.commonProp(Object),calls Component Component$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropMissingInConditionalBad(boolean):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropMissingInConditionalBad(boolean):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropResInCondOk_FP(boolean):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop is required for component codetoanalyze.java.litho.ResPropComponent, but is not set before the call to build(),calls ResPropComponent$Builder ResPropComponent.create(),calls ResPropComponent ResPropComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropResInCondOneNormalOk_FP(boolean):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop is required for component codetoanalyze.java.litho.ResPropComponent, but is not set before the call to build(),calls ResPropComponent$Builder ResPropComponent.create(),calls ResPropComponent ResPropComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropResMissingBad():void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop is required for component codetoanalyze.java.litho.ResPropComponent, but is not set before the call to build(),calls ResPropComponent$Builder ResPropComponent.create(),calls ResPropComponent ResPropComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildPropVarArgMissingBad():void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [Either @Prop props or @Prop(varArg = prop) is required for component codetoanalyze.java.litho.VarArgPropComponent, but is not set before the call to build(),calls VarArgPropComponent$Builder VarArgPropComponent.create(),calls VarArgPropComponent VarArgPropComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildWithColumnChildBad():void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop1(Object),calls Component Component$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildWithout1Bad():com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.buildWithout3Bad():com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop1(Object),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.callBuildSuffixWithoutRequiredBad():com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.castImpossibleOk_FP(java.lang.Object):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.castImpossibleOk_FP(java.lang.Object):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.castMissingOneBad(java.lang.Object):void, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop2(Object),calls MyLithoComponent MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.generalTypeForgot3Bad():java.lang.Object, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop1(Object),calls Component MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.missingProp1InBothBranchesBeforeBuildBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls Component MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.missingProp1InBothBranchesBeforeBuildBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop2(Object),calls Component MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.missingProp2InOneBranchBeforeBuildBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop2 is required for component com.facebook.litho.MyLithoComponent, but is not set before the call to build(),calls MyLithoComponent$Builder MyLithoComponent.create(),calls MyLithoComponent$Builder MyLithoComponent$Builder.prop1(Object),calls Component MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.missingProp3InOneBranchBeforeBuildBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop1(Object),calls Component MyLithoComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setProp3InCalleeButForgetProp1Bad():com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredEffectful_FP(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredOnBothBranchesMissingProp3Bad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredOnBothBranchesMissingProp3Bad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop3 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredOnBothBranchesNoAssignOk_FP(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredOnOneBothBranchesWithCreateOk_FP(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredOnOneBranchBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
codetoanalyze/java/litho/RequiredProps.java, codetoanalyze.java.litho.RequiredProps.setRequiredOnOneBranchEffectfulBad(boolean):com.facebook.litho.Component, 0, MISSING_REQUIRED_PROP, no_bucket, ERROR, [@Prop prop1 is required for component codetoanalyze.java.litho.MyComponent, but is not set before the call to build(),calls MyComponent$Builder MyComponent.create(),calls MyComponent$Builder MyComponent$Builder.prop2(Object),calls MyComponent$Builder MyComponent$Builder.prop3(Object),calls MyComponent MyComponent$Builder.build()]
Loading…
Cancel
Save