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 + -
显示快捷键?