dialyzer_bif_constraints.inc

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

INC
515
字号
%% This is an -*- erlang -*- file%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% Copyright 2006, Tobias Lindahl and Kostis Sagonas%% %%     $Id$%%get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State)   when Op =:= '+'; Op =:= '-'; Op =:= '*' ->  ReturnType = mk_fun_var(fun(Map)-> 			      TmpArgTypes = lookup_type_list(Args, Map),			      erl_bif_types:type(erlang, Op, 2, TmpArgTypes)			  end, Args),  ArgFun =     fun(A, Pos) ->	F = 	  fun(Map)->	      DstType = lookup_type(Dst, Map),	      AType = lookup_type(A, Map),	      case t_is_integer(DstType) of		true ->		  case t_is_integer(AType) of		    true -> 		      eval_inv_arith(Op, Pos, DstType, AType);		    false  ->		      %% This must be temporary.		      t_integer()		  end;		false ->		  case t_is_float(DstType) of		    true -> 		      case t_is_integer(AType) of			true -> t_float();			false -> t_number()		      end;		    false ->		      t_number()		  end	      end	  end,	mk_fun_var(F, [Dst, A])    end,  Arg1FunVar = ArgFun(Arg2, 2),  Arg2FunVar = ArgFun(Arg1, 1),  mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType),			   mk_constraint(Arg1, sub, Arg1FunVar),			   mk_constraint(Arg2, sub, Arg2FunVar)]);get_bif_constr({erlang, Op, 2}, Dst, Args = [Arg1, Arg2], _State)   when Op =:= '<'; Op =:= '=<'; Op =:= '>'; Op =:= '>=' ->  ArgFun =     fun(LocalArg1, LocalArg2, LocalOp) ->	fun(Map) ->	    DstType = lookup_type(Dst, Map),	    IsTrue = t_is_atom(true, DstType),	    IsFalse = t_is_atom(false, DstType),	    case IsTrue orelse IsFalse of	      true ->		Arg1Type = lookup_type(LocalArg1, Map),		Arg2Type = lookup_type(LocalArg2, Map),		case t_is_integer(Arg1Type) andalso t_is_integer(Arg2Type) of		  true ->		    Max1 = erl_types:number_max(Arg1Type),		    Min1 = erl_types:number_min(Arg1Type),		    Max2 = erl_types:number_max(Arg2Type),		    Min2 = erl_types:number_min(Arg2Type),		    case LocalOp of		      '=<' -> 			if IsTrue  -> t_from_range(Min1, Max2);			   IsFalse -> t_from_range(range_inc(Min2), Max1)			end;		      '<'  -> 			if IsTrue  -> t_from_range(Min1, range_dec(Max2));			   IsFalse -> t_from_range(Min2, Max1)			end;		      '>=' -> 			if IsTrue  -> t_from_range(Min2, Max1);			   IsFalse -> t_from_range(Min1, range_dec(Max2))			end;		      '>'  -> 			if IsTrue  -> t_from_range(range_inc(Min2), Max1);			   IsFalse -> t_from_range(Min1, Max2)			end		    end;		  false -> t_any()		end;	      false -> t_any()	    end	end    end,  {Arg1Fun, Arg2Fun} =    case Op of      '<'  -> {ArgFun(Arg1, Arg2, '<'),  ArgFun(Arg2, Arg1, '>=')};      '=<' -> {ArgFun(Arg1, Arg2, '=<'), ArgFun(Arg2, Arg1, '>=')};      '>'  -> {ArgFun(Arg1, Arg2, '>'),  ArgFun(Arg2, Arg1, '<')};      '>=' -> {ArgFun(Arg1, Arg2, '>='), ArgFun(Arg2, Arg1, '=<')}    end,  Arg1Var = mk_fun_var(Arg1Fun, [Dst, Arg1, Arg2]),  Arg2Var = mk_fun_var(Arg2Fun, [Dst, Arg1, Arg2]),  DstVar = mk_fun_var(fun(Map)-> 			  TmpArgTypes = lookup_type_list(Args, Map),			  erl_bif_types:type(erlang, Op, 2, TmpArgTypes)		      end, Args),  mk_conj_constraint_list([mk_constraint(Dst, sub, DstVar),			   mk_constraint(Arg1, sub, Arg1Var),			   mk_constraint(Arg2, sub, Arg2Var)]);get_bif_constr({erlang, '++', 2}, Dst, Args = [Hd, Tl], _State) ->  HdFun = fun(Map) ->	      DstType = lookup_type(Dst, Map),	      case t_is_cons(DstType) of		true -> t_list(t_cons_hd(DstType));		false -> 		  case t_is_list(DstType) of		    true -> 		      case t_is_nil(DstType) of			true -> DstType;			false -> t_list(t_list_elements(DstType))		      end;		    false -> t_list() 		  end	      end	  end,  TlFun = fun(Map) ->	      DstType = lookup_type(Dst, Map),	      case t_is_cons(DstType) of		true -> t_sup(t_cons_tl(DstType), DstType);		false ->		  case t_is_list(DstType) of		    true -> 		      case t_is_nil(DstType) of			true -> DstType;			false -> t_list(t_list_elements(DstType))		      end;		    false -> t_any()		  end	      end	  end,  HdVar = mk_fun_var(HdFun, [Dst]),    TlVar = mk_fun_var(TlFun, [Dst]),  ArgTypes = erl_bif_types:arg_types(erlang, '++', 2),  ReturnType = mk_fun_var(fun(Map)-> 			      TmpArgTypes = lookup_type_list(Args, Map),			      erl_bif_types:type(erlang, '++', 2, TmpArgTypes)			  end, Args),  Cs = mk_constraints(Args, sub, ArgTypes),  mk_conj_constraint_list([mk_constraint(Dst, sub, ReturnType),			   mk_constraint(Hd, sub, HdVar),			   mk_constraint(Tl, sub, TlVar)			   |Cs]);get_bif_constr({erlang, is_atom, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_atom());get_bif_constr({erlang, is_binary, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_binary());get_bif_constr({erlang, is_boolean, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_bool());get_bif_constr({erlang, is_float, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_float());get_bif_constr({erlang, is_function, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_fun());get_bif_constr({erlang, is_function, 2}, Dst, [Fun, Arity], _State) ->  ArgFun = fun(Map) ->	       DstType = lookup_type(Dst, Map),	       case t_is_atom(true, DstType) of		 true -> 		   ArityType = lookup_type(Arity, Map),		   case t_number_vals(ArityType) of		     any -> t_fun();		     Vals -> t_sup([t_fun(X, t_any()) || X <- Vals])		   end;		 false -> t_any()	       end	   end,  ArgV = mk_fun_var(ArgFun, [Dst, Arity]),  mk_conj_constraint_list([mk_constraint(Dst, sub, t_bool()),			   mk_constraint(Arity, sub, t_integer()),			   mk_constraint(Fun, sub, ArgV)]);get_bif_constr({erlang, is_integer, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_integer());get_bif_constr({erlang, is_list, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_pos_improper_list());get_bif_constr({erlang, is_number, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_number());get_bif_constr({erlang, is_pid, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_pid());get_bif_constr({erlang, is_port, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_port());get_bif_constr({erlang, is_reference, 1}, Dst, [Arg], _State) ->  get_bif_test_constr(Dst, Arg, t_ref());get_bif_constr({erlang, is_record, 3}, Dst, [Var, Tag, Arity] = Args, State) ->  %% TODO: Revise this to make it precise for Tag and Arity.  ArgFun =     fun(Map) ->	case t_is_atom(true, lookup_type(Dst, Map)) of	  true ->	    ArityType = lookup_type(Arity, Map),	    case t_is_integer(ArityType) of	      true ->		case t_number_vals(ArityType) of		  [ArityVal] ->		    TagType = lookup_type(Tag, Map),		    case t_is_atom(TagType) of		      true ->			GenRecord = t_tuple([TagType|					     duplicate(ArityVal-1, t_any())]),			case t_atom_vals(TagType) of			  [TagVal] ->			    case state__lookup_record(State, TagVal, 						      ArityVal - 1) of			      {ok, Type} ->  Type;			      error -> GenRecord			    end;			  _ -> GenRecord			end;		      false -> t_tuple(ArityVal)		    end;		  _ -> t_tuple()		end;	      false -> t_tuple()	    end;	  false -> t_any()	end    end,  ArgV = mk_fun_var(ArgFun, [Tag, Arity, Dst]),  DstFun = fun(Map) -> 	       TmpArgTypes = lookup_type_list(Args, Map),	       erl_bif_types:type(erlang, is_record, 3, TmpArgTypes)	   end,  DstV = mk_fun_var(DstFun, Args),    mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),			   mk_constraint(Arity, sub, t_integer()),			   mk_constraint(Tag, sub, t_atom()),			   mk_constraint(Var, sub, ArgV)]);get_bif_constr({erlang, is_record, 2}, Dst, Args = [Var, Tag], _State) ->  ArgFun = fun(Map) ->	       case t_is_atom(true, lookup_type(Dst, Map)) of		 true -> t_tuple();		 false -> t_any()	       end	   end,  ArgV = mk_fun_var(ArgFun, [Dst]),  DstFun = fun(Map) -> 	       TmpArgTypes = lookup_type_list(Args, Map),	       erl_bif_types:type(erlang, is_record, 2, TmpArgTypes)	   end,  DstV = mk_fun_var(DstFun, Args),  mk_conj_constraint_list([mk_constraint(Dst, sub, DstV),			   mk_constraint(Tag, sub, t_atom()),			   mk_constraint(Var, sub, ArgV)]);

⌨️ 快捷键说明

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