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