ictype.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,412 行 · 第 1/3 页
ERL
1,412 行
%% ``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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %% $Id$%%-module(ictype).-include("ic.hrl").-include("icforms.hrl").%%-----------------------------------------------------------------%% External exports%%------------------------------------------------------------------export([type_check/2, scoped_lookup/4, maybe_array/5, to_uppercase/1]).-export([name2type/2, member2type/3, isBasicTypeOrEterm/3, isEterm/3]).-export([isBasicType/1, isBasicType/2, isBasicType/3, isString/3, isWString/3, isArray/3, isStruct/3, isUnion/3, isEnum/3, isSequence/3, isBoolean/3 ]).-export([fetchTk/3, fetchType/1, tk/4]).%%-----------------------------------------------------------------%% Internal exports%%------------------------------------------------------------------export([]).%%-----------------------------------------------------------------%% Macros%%-----------------------------------------------------------------%%-define(DBG(F,A), io:format(F,A)).-define(DBG(F,A), true).-define(STDDBG, ?DBG(" dbg: ~p: ~p~n", [element(1,X), ic_forms:get_id2(X)])).%%-----------------------------------------------------------------%% External functions%%-----------------------------------------------------------------type_check(G, Forms) -> S = ic_genobj:tktab(G), check_list(G, S, [], Forms).scoped_lookup(G, S, N, X) -> Id = ic_symtab:scoped_id_strip(X), case ic_symtab:scoped_id_is_global(X) of true -> lookup(G, S, [], X, Id); false -> lookup(G, S, N, X, Id) end.%%--------------------------------------------------------------------%% maybe_array%%%% Array declarators are indicated on the declarator and not on%% the type, therefore the declarator decides if the array type%% kind is added or not.%%maybe_array(G, S, N, X, TK) when record(X, array) -> mk_array(G, S, N, X#array.size, TK);maybe_array(_G, _S, _N, _, TK) -> TK.name2type(G, Name) -> S = ic_genobj:tktab(G), ScopedName = lists:reverse(string:tokens(Name, "_")), InfoList = ets:lookup(S, ScopedName ), filter( InfoList ).%% This is en overloaded function,%% differs in input on unionsmember2type(_G, X, I) when record(X, union)-> Name = ic_forms:get_id2(I), case lists:keysearch(Name,2,element(6,X#union.tk)) of false -> error; {value,Rec} -> fetchType(element(3,Rec)) end;member2type( G, SName, MName ) -> S = ic_genobj:tktab( G ), SNList = lists:reverse(string:tokens(SName,"_")), ScopedName = [MName | SNList], InfoList = ets:lookup( S, ScopedName ), case filter( InfoList ) of error -> %% Try a little harder, seeking inside tktab case lookup_member_type_in_tktab(S, ScopedName, MName) of error -> %% Check if this is the "return to return1" case case MName of "return1" -> %% Do it all over again ! ScopedName2 = ["return" | SNList], InfoList2 = ets:lookup( S, ScopedName2 ), case filter( InfoList2 ) of error -> %% Last resort: seek in pragma table lookup_type_in_pragmatab(G, SName); Other -> Other end; _ -> %% Last resort: seek in pragma table lookup_type_in_pragmatab(G, SName) end; Other -> Other end; Other -> Other end.lookup_member_type_in_tktab(S, ScopedName, MName) -> case ets:match_object(S, {'_',member,{MName,'_'},nil}) of [] -> error; [{_FullScopedName,member,{MName,TKInfo},nil}]-> fetchType( TKInfo ); List -> lookup_member_type_in_tktab(List,ScopedName) end.lookup_member_type_in_tktab([], _ScopedName) -> error;lookup_member_type_in_tktab([{FullScopedName,_,{_,TKInfo},_}|Rest],ScopedName) -> case lists:reverse(string:tokens(ic_util:to_undersc(FullScopedName),"_")) of ScopedName -> fetchType(TKInfo); _ -> lookup_member_type_in_tktab(Rest,ScopedName) end.lookup_type_in_pragmatab(G, SName) -> S = ic_genobj:pragmatab(G), %% Look locally first case ets:match(S,{file_data_local,'_','_','$2','_','_',SName,'_','_'}) of [] -> %% No match, seek included case ets:match(S,{file_data_included,'_','_','$2','_','_',SName,'_','_'}) of [] -> error; [[Type]] -> io:format("1 Found(~p) : ~p~n",[SName,Type]), Type end; [[Type]] -> io:format("2 Found(~p) : ~p~n",[SName,Type]), Type end.isString(G, N, T) when element(1, T) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_string',_}, _} -> true; _ -> false end; isString(_G, _N, T) when record(T, string) -> true;isString(_G, _N, _Other) -> false. isWString(G, N, T) when element(1, T) == scoped_id -> %% WSTRING case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_wstring',_}, _} -> true; _ -> false end; isWString(_G, _N, T) when record(T, wstring) -> true;isWString(_G, _N, _Other) -> false. isArray(G, N, T) when element(1, T) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_array', _, _}, _} -> true; _ -> false end; isArray(_G, _N, T) when record(T, array) -> true;isArray(_G, _N, _Other) -> false. isSequence(G, N, T) when element(1, T) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_sequence', _, _}, _} -> true; _ -> false end; isSequence(_G, _N, T) when record(T, sequence) -> true;isSequence(_G, _N, _Other) -> false. isStruct(G, N, T) when element(1, T) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_struct', _, _, _}, _} -> true; _ -> false end; isStruct(_G, _N, T) when record(T, struct) -> true;isStruct(_G, _N, _Other) -> false.isUnion(G, N, T) when element(1, T) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_union', _, _, _,_,_}, _} -> true; _Other -> false end; isUnion(_G, _N, T) when record(T, union) -> true;isUnion(_G, _N, _Other) -> false.isEnum(G, N, T) when element(1, T) == scoped_id -> case ic_symtab:get_full_scoped_name(G, N, T) of {_FullScopedName, _, {'tk_enum',_,_,_}, _} -> true; _Other -> false end; isEnum(_G, _N, T) when record(T, enum) -> true;isEnum(_G, _N, _Other) -> false.isBoolean(G, N, T) when element(1, T) == scoped_id -> {_, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), case fetchType(TK) of 'boolean' -> true; _ -> false end;isBoolean(_, _, {'tk_boolean',_}) -> true;isBoolean(_, _, {'boolean',_}) -> true;isBoolean(_, _, _) -> false.%%% Just used for CisBasicTypeOrEterm(G, N, S) -> case isBasicType(G, N, S) of true -> true; false -> isEterm(G, N, S) end.isEterm(G, N, S) when element(1, S) == scoped_id -> {FullScopedName, _, _TK, _} = ic_symtab:get_full_scoped_name(G, N, S), case ic_code:get_basetype(G, ic_util:to_undersc(FullScopedName)) of "erlang_term" -> true; "ETERM*" -> true; _X -> false end;isEterm(_G, _Ni, _X) -> false.isBasicType(_G, _N, {scoped_id,_,_,["term","erlang"]}) -> false;isBasicType(G, N, S) when element(1, S) == scoped_id -> {_, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, S), isBasicType(fetchType(TK));isBasicType(_G, _N, {string, _} ) -> false;isBasicType(_G, _N, {wstring, _} ) -> %% WSTRING false;isBasicType(_G, _N, {unsigned, {long, _}} ) -> true;isBasicType(_G, _N, {unsigned, {short, _}} ) -> true;isBasicType(_G, _N, {Type, _} ) -> isBasicType(Type);isBasicType(_G, _N, _X) -> false.isBasicType( G, Name ) -> isBasicType( name2type( G, Name ) ).isBasicType( Type ) -> lists:member(Type, [tk_short,short, tk_long,long, tk_longlong,longlong, %% LLONG tk_ushort,ushort, tk_ulong,ulong, tk_ulonglong,ulonglong, %% ULLONG tk_float,float, tk_double,double, tk_boolean,boolean, tk_char,char, tk_wchar,wchar, %% WCHAR tk_octet,octet, tk_any,any]). %% Fix for any%%-----------------------------------------------------------------%% Internal functions%%-----------------------------------------------------------------check(G, _S, N, X) when record(X, preproc) -> handle_preproc(G, N, X#preproc.cat, X), X;check(G, S, N, X) when record(X, op) -> ?STDDBG, TK = tk_base(G, S, N, ic_forms:get_type(X)), tktab_add(G, S, N, X), N2 = [ic_forms:get_id2(X) | N], Ps = lists:map(fun(P) -> tktab_add(G, S, N2, P), P#param{tk=tk_base(G, S, N, ic_forms:get_type(P))} end, X#op.params), %% Check for exception defs. Raises = lists:map(fun(E) -> name_lookup(G, S, N, E) end, X#op.raises), case ic_forms:is_oneway(X) of true -> if TK /= tk_void -> ic_error:error(G, {bad_oneway_type, X, TK}); true -> ok end, case ic:filter_params([inout, out], X#op.params) of [] -> ok; % No out parameters! _ -> ic_error:error(G, {oneway_outparams, X}) end, case X#op.raises of [] -> ok; _ -> ic_error:error(G, {oneway_raises, X}) end; false -> ok end, X#op{params=Ps, tk=TK, raises=Raises};check(G, S, N, X) when record(X, interface) -> ?STDDBG, N2 = [ic_forms:get_id2(X) | N], TK = {tk_objref, ictk:get_IR_ID(G, N, X), ic_forms:get_id2(X)}, Inherit = inherit_resolve(G, S, N, X#interface.inherit, []), tktab_add(G, S, N, X, TK, Inherit), CheckedBody = check_list(G, S, N2, ic_forms:get_body(X)), InhBody = calc_inherit_body(G, N2, CheckedBody, Inherit, []), X2 = X#interface{inherit=Inherit, tk=TK, body=CheckedBody, inherit_body=InhBody}, ic_symtab:store(G, N, X2), X2;check(G, S, N, X) when record(X, forward) -> ?STDDBG, tktab_add(G, S, N, X, {tk_objref, ictk:get_IR_ID(G, N, X), ic_forms:get_id2(X)}), X;check(G, S, N, X) when record(X, const) -> ?STDDBG, case tk_base(G, S, N, ic_forms:get_type(X)) of Err when element(1, Err) == error -> X; TK -> check_const_tk(G, S, N, X, TK), case iceval:eval_const(G, S, N, TK, X#const.val) of Err when element(1, Err) == error -> X; {ok, NewTK, Val} -> V = iceval:get_val(Val), tktab_add(G, S, N, X, NewTK, V), X#const{val=V, tk=NewTK}; Val -> V = iceval:get_val(Val), tktab_add(G, S, N, X, TK, V), X#const{val=V, tk=TK} end end;check(G, S, N, X) when record(X, const) -> ?STDDBG, case tk_base(G, S, N, ic_forms:get_type(X)) of Err when element(1, Err) == error -> X; TK -> check_const_tk(G, S, N, X, TK), case iceval:eval_const(G, S, N, TK, X#const.val) of Err when element(1, Err) == error -> X; Val -> V = iceval:get_val(Val), tktab_add(G, S, N, X, TK, V), X#const{val=V, tk=TK} end end;check(G, S, N, X) when record(X, except) -> ?STDDBG, TK = tk(G, S, N, X), X#except{tk=TK};check(G, S, N, X) when record(X, struct) -> ?STDDBG, TK = tk(G, S, N, X), X#struct{tk=TK};check(G, S, N, X) when record(X, enum) -> ?STDDBG, TK = tk(G, S, N, X), X#enum{tk=TK};check(G, S, N, X) when record(X, union) -> ?STDDBG, TK = tk(G, S, N, X), X#union{tk=TK};check(G, S, N, X) when record(X, attr) -> ?STDDBG, TK = tk_base(G, S, N, ic_forms:get_type(X)), XX = #id_of{type=X}, lists:foreach(fun(Id) -> tktab_add(G, S, N, XX#id_of{id=Id}) end, ic_forms:get_idlist(X)), X#attr{tk=TK};check(G, S, N, X) when record(X, module) ->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?