dialyzer_bif_constraints.inc

来自「OTP是开放电信平台的简称」· INC 代码 · 共 515 行 · 第 1/2 页

INC
515
字号
get_bif_constr({erlang, is_tuple, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_tuple());get_bif_constr({erlang, 'and', 2}, Dst, [Arg1, Arg2], _State) ->  True = t_from_term(true),  False = t_from_term(false),  ArgFun = fun(Var) ->	       fun(Map) ->		   DstType = lookup_type(Dst, Map),		   case t_is_atom(true, DstType) of		     true -> True;		     false ->		       case t_is_atom(false, DstType) of			 true ->			   case t_is_atom(true, lookup_type(Var, Map)) of			     true -> False;			     false -> t_bool()			   end;			 false -> 			   t_bool()		       end		   end	       end	   end,  DstFun = fun(Map) ->	       Arg1Type = lookup_type(Arg1, Map),	       case t_is_atom(false, Arg1Type) of		 true -> False;		 false ->		   Arg2Type = lookup_type(Arg2, Map),		   case t_is_atom(false, Arg2Type) of		     true -> False;		     false ->		       case (t_is_atom(true, Arg1Type) 			     andalso t_is_atom(true, Arg2Type)) of			 true -> True;			 false -> t_bool()		       end		   end	       end	   end,  ArgV1 = mk_fun_var(ArgFun(Arg2), [Arg2, Dst]),  ArgV2 = mk_fun_var(ArgFun(Arg1), [Arg1, Dst]),  DstV = mk_fun_var(DstFun, [Arg1, Arg2]),  mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),			   mk_constraint(Arg1, sub, ArgV1),			   mk_constraint(Arg2, sub, ArgV2)]);get_bif_constr({erlang, 'or', 2}, Dst, [Arg1, Arg2], _State) ->  True = t_from_term(true),  False = t_from_term(false),  ArgFun = fun(Var) ->	       fun(Map) ->		   DstType = lookup_type(Dst, Map),		   case t_is_atom(false, DstType) of		     true -> False;		     false ->		       case t_is_atom(true, DstType) of			 true ->			   case t_is_atom(false, lookup_type(Var, Map)) of			     true -> True;			     false -> t_bool()			   end;			 false -> 			   t_bool()		       end		   end	       end	   end,  DstFun = fun(Map) ->	       Arg1Type = lookup_type(Arg1, Map),	       case t_is_atom(true, Arg1Type) of		 true -> True;		 false ->		   Arg2Type = lookup_type(Arg2, Map),		   case t_is_atom(true, Arg2Type) of		     true -> True;		     false ->		       case (t_is_atom(false, Arg1Type) 			     andalso t_is_atom(false, Arg2Type)) of			 true -> False;			 false -> t_bool()		       end		   end	       end	   end,  ArgV1 = mk_fun_var(ArgFun(Arg2), [Arg2, Dst]),  ArgV2 = mk_fun_var(ArgFun(Arg1), [Arg1, Dst]),  DstV = mk_fun_var(DstFun, [Arg1, Arg2]),  Disj = mk_disj_constraint_list([mk_constraint(Arg1, sub, True),				  mk_constraint(Arg2, sub, True),				  mk_constraint(Dst, sub, False)]),  mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),			   mk_constraint(Arg1, sub, ArgV1),			   mk_constraint(Arg2, sub, ArgV2),			   Disj]);get_bif_constr({erlang, 'not', 1}, Dst, [Arg], _State) ->  True = t_from_term(true),  False = t_from_term(false),  Fun = fun(Var) -> 	    fun(Map) ->		Type = lookup_type(Var, Map),		case t_is_atom(true, Type) of		  true -> False;		  false ->		    case t_is_atom(false, Type) of		      true -> True;		      false -> t_bool()		    end		end	    end	end,  ArgV = mk_fun_var(Fun(Dst), [Dst]),  DstV = mk_fun_var(Fun(Arg), [Arg]),  mk_conj_constraint_list([mk_constraint(Arg, sub, ArgV),			   mk_constraint(Dst, sub, DstV)]);get_bif_constr({erlang, '=:=', 2}, Dst, [Arg1, Arg2], _State) ->  ArgFun =    fun(Self, OtherVar) ->	fun(Map) ->	    DstType = lookup_type(Dst, Map),	    OtherVarType = lookup_type(OtherVar, Map),	    case t_is_atom(true, DstType) of	      true -> OtherVarType;	      false -> 		case t_is_atom(false, DstType) of		  true ->		    case is_singleton_type(OtherVarType) of		      true -> t_subtract(lookup_type(Self, Map), OtherVarType);		      false -> t_any()		    end;		  false ->		    t_any()		end	    end	end    end,  DstFun = fun(Map) ->	       ArgType1 = lookup_type(Arg1, Map),	       ArgType2 = lookup_type(Arg2, Map),	       case t_is_none(t_inf(ArgType1, ArgType2)) of		 true -> t_from_term(false);		 false -> t_bool()	       end	   end,  ArgV1 = mk_fun_var(ArgFun(Arg1, Arg2), [Dst, Arg1, Arg2]),  ArgV2 = mk_fun_var(ArgFun(Arg2, Arg1), [Dst, Arg1, Arg2]),  DstV = mk_fun_var(DstFun, [Arg1, Arg2]),  mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),			   mk_constraint(Arg1, sub, ArgV1),			   mk_constraint(Arg2, sub, ArgV2)]);get_bif_constr({erlang, '==', 2}, Dst, Args = [Arg1, Arg2], _State) ->  DstFun = fun(Map) ->	       TmpArgTypes = lookup_type_list(Args, Map),	       erl_bif_types:type(erlang, '==', 2, TmpArgTypes)	   end,  ArgFun =    fun(Var, Self) ->	fun(Map) ->	    VarType = lookup_type(Var, Map),	    DstType = lookup_type(Dst, Map),	    case is_singleton_non_number_type(VarType) of	      true ->		case t_is_atom(true, DstType) of		  true -> VarType;		  false ->		    case t_is_atom(false, DstType) of		      true -> t_subtract(lookup_type(Self, Map), VarType);		      false -> t_any()		    end		end;	      false ->		case t_is_atom(true, DstType) of		  true ->		    case t_is_number(VarType) of		      true -> t_number();		      false -> 			case t_is_atom(VarType) of			  true -> VarType;			  false -> t_any()			end		    end;		  false ->		    t_any()		end	    end	end    end,  DstV = mk_fun_var(DstFun, Args),  ArgV1 = mk_fun_var(ArgFun(Arg2, Arg1), [Arg1, Arg2, Dst]),  ArgV2 = mk_fun_var(ArgFun(Arg1, Arg2), [Arg1, Arg2, Dst]),  mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),			   mk_constraint(Arg1, sub, ArgV1),			   mk_constraint(Arg2, sub, ArgV2)]);get_bif_constr({M, F, A}, Dst, Args, _State) ->  GenType = erl_bif_types:type(M, F, A),  case t_is_none(GenType) of    true -> ?debug("Bif: ~w failed\n", [{M, F, A}]), throw(error);    false ->      ArgTypes = erl_bif_types:arg_types(M, F, A),      ReturnType = mk_fun_var(fun(Map)-> 				  TmpArgTypes = lookup_type_list(Args, Map),				  erl_bif_types:type(M, F, A, TmpArgTypes)			      end, Args),      case ArgTypes =:= any of	true -> 	  case t_is_any(GenType) of	    true -> 	      none;	    false ->	      mk_constraint(Dst, sub, ReturnType)	  end;	false -> 	  Cs = mk_constraints(Args, sub, ArgTypes),	  mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType)|Cs])      end  end.eval_inv_arith('+', _Pos, Dst, Arg) ->   erl_bif_types:type(erlang, '-', 2, [Dst, Arg]);eval_inv_arith('*', _Pos, Dst, Arg) ->   case t_number_vals(Arg) of    [0] -> t_integer();    _ ->       TmpRet = erl_bif_types:type(erlang, 'div', 2, [Dst, Arg]),      Zero = t_from_term(0),      %% If 0 is not part of the result, it cannot be part of the argument.      case t_is_subtype(Zero, Dst) of	false -> t_subtract(TmpRet, Zero);	true -> TmpRet      end  end;eval_inv_arith('-', 1, Dst, Arg) ->   erl_bif_types:type(erlang, '-', 2, [Arg, Dst]);eval_inv_arith('-', 2, Dst, Arg) ->   erl_bif_types:type(erlang, '+', 2, [Arg, Dst]).range_inc(neg_inf) -> neg_inf;range_inc(pos_inf) -> pos_inf;range_inc(Int) when is_integer(Int) -> Int + 1.range_dec(neg_inf) -> neg_inf;range_dec(pos_inf) -> pos_inf;range_dec(Int) when is_integer(Int) -> Int - 1.  get_bif_test_constr(Dst, Arg, Type) ->  ArgFun = fun(Map) ->	       DstType = lookup_type(Dst, Map),	       case t_is_atom(true, DstType) of		 true -> Type;		 false -> t_any()	       end	   end,  ArgV = mk_fun_var(ArgFun, [Dst]),  mk_conj_constraint_list([mk_constraint(Dst, sub, t_bool()),			   mk_constraint(Arg, sub, ArgV)]).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?