ic_erlbe.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,140 行 · 第 1/3 页

ERL
1,140
字号
			{Get, Set} = mk_attr_func_names([], get_id(Id)),			case A#attr.readonly of			    {readonly, _} -> [{Get, 1} | Acc2];			    _ ->             [{Get, 1}, {Set, 2} | Acc2]			end end, Acc, ic_forms:get_idlist(A));exp3(_G, _N, _X, Acc, _BE) -> Acc.exp_list(G, N, L, OrigAcc, BE) ->     lists:foldr(fun(X, Acc) -> exp3(G, N, X, Acc, BE) end, OrigAcc, L).%%------------------------------------------------------------%%%% Emit stuff%%%%	Low level generation primitives%%emit_stub_func(G, N, X, Name, ArgNames, _TypeList, OutArgs, Oneway, Backend) ->    case ic_genobj:is_stubfile_open(G) of	false -> 	    ok;	true ->	    Fd = ic_genobj:stubfiled(G),	    StubName = list_to_atom(Name),	    UsingTimeout = use_timeout(G, N, X),	    Timeout = case UsingTimeout of			  true ->			      mk_name(G, "Timeout");			  false ->			      "infinity"		      end,	    Options = mk_name(G, "Options"),	    This = mk_name(G, "THIS"),	    CallOrCast = 		case is_oneway(X) of 		    true -> ?CAST; 		    _ -> ?CALL		end,	    emit_op_comment(G, Fd, X, StubName, ArgNames, OutArgs),	    case Backend of		erl_corba ->		    emit(Fd, "~p(~s) ->\n", 			 [StubName, mk_list([This | ArgNames])]),		    emit(Fd, "    ~s:~s(~s, ~p, [~s], ?MODULE).\n\n", 			 [?CORBAMOD, CallOrCast, This, StubName, mk_list(ArgNames)]),		    emit(Fd, "~p(~s) ->\n", 			 [StubName, mk_list([This, Options| ArgNames])]),		    emit(Fd, "    ~s:~s(~s, ~p, [~s], ?MODULE, ~s).\n\n", 			 [?CORBAMOD, CallOrCast, This, StubName, mk_list(ArgNames),			  Options]);		_  ->		    FunName = case ic_options:get_opt(G, scoped_op_calls) of 				  true -> 				      list_to_atom(ic_util:to_undersc([Name | N]));				  false ->				      StubName			      end,		    %% NO TimeOut on ONEWAYS here !!!!		    case Oneway of 			true ->			    emit(Fd, "~p(~s) ->\n", 				 [StubName, mk_list([This | ArgNames])]);			false ->			    case UsingTimeout of				true ->				    emit(Fd, "~p(~s) ->\n",					 [StubName, mk_list([This, Timeout| ArgNames])]);				false ->				    emit(Fd, "~p(~s) ->\n", 					 [StubName, mk_list([This | ArgNames])])			    end		    end,		    		    %% NO TimeOut on ONEWAYS here !!!!		    if 			length(ArgNames) == 0 ->			    case is_oneway(X) of 				true ->				    emit(Fd, "    ~s:~s(~s, ~p).\n\n",					 [?GENSERVMOD, CallOrCast, This, FunName]);				false ->				    emit(Fd, "    ~s:~s(~s, ~p, ~s).\n\n",					 [?GENSERVMOD, CallOrCast, This, FunName, Timeout])			    end;			true ->			    case is_oneway(X) of 				true ->				    emit(Fd, "    ~s:~s(~s, {~p, ~s}).\n\n", 					 [?GENSERVMOD, CallOrCast, This, FunName,					  mk_list(ArgNames)]);				false ->				    emit(Fd, "    ~s:~s(~s, {~p, ~s}, ~s).\n\n", 					 [?GENSERVMOD, CallOrCast, This, FunName,					  mk_list(ArgNames), Timeout])			    end		    end	    end    end.emit_skel_func(G, N, X, OpName, ArgNames, TypeList, OutArgs, Oneway, Backend) ->    case ic_genobj:is_stubfile_open(G) of	false -> 	    ok;	true ->	    emit_skel_func_helper(G, N, X, OpName, ArgNames, TypeList, OutArgs, 				  Oneway, Backend)    end.emit_skel_func_helper(G, N, X, OpName, ArgNames, _TypeList, OutArgs, Oneway, 		      erl_corba) ->    Fd = ic_genobj:stubfiled(G),    Name	= list_to_atom(OpName),    ImplF	= Name,    ImplM	= list_to_atom(ic_genobj:impl(G)),    ThisStr	= mk_name(G, "THIS"),    FromStr	= mk_name(G, "From"),    State	= mk_name(G, "State"),    Context	= mk_name(G, "Context"),    {UseFrom, From} =	case Oneway of	    false ->		case use_from(G, N, OpName) of		    true ->			{FromStr, FromStr};		    false ->			{"false", "_"}		end;	    true ->		{"false", "_"}	end,    {UseThis, This} =	case use_this(G, N, OpName) of	    true ->		{ThisStr, ThisStr};	    false ->		{"false", "_"}	end,    %% Create argument list string    CallArgs = mk_list(ArgNames),    emit_op_comment(G, Fd, X, Name, ArgNames, OutArgs),        %% Check if pre and post conditions are specified for this operation    Precond = use_precond(G, N, X),    Postcond = use_postcond(G, N, X),        case Oneway of	true ->	    emit(Fd, "handle_cast({~s, ~s, ~p, [~s]}, ~s) ->\n",		 [This, Context, Name, CallArgs, State]),	    case {Precond, Postcond} of		{false, false} ->		    emit(Fd, "    corba:handle_cast(~p, ~p, [~s], ~s, ~s, ~s);\n\n", 			 [ImplM, ImplF, CallArgs, State, Context, UseThis]);		_ ->		    emit(Fd, "    corba:handle_cast(~p, ~p, [~s], ~s, ~s, ~s, ~p, ~p, ?MODULE);\n\n", 			 [ImplM, ImplF, CallArgs, State, Context, UseThis, 			  Precond, Precond])	    end;	false ->	    emit(Fd, "handle_call({~s, ~s, ~p, [~s]}, ~s, ~s) ->\n",		 [This, Context, Name, CallArgs, From, State]),	    case {Precond, Postcond} of		{false, false} ->		    emit(Fd, "  corba:handle_call(~p, ~p, [~s], ~s, ~s, ~s, ~s);\n\n", 			 [ImplM, ImplF, CallArgs, State, Context, UseThis, UseFrom]);		_->		    emit(Fd, "  corba:handle_call(~p, ~p, [~s], ~s, ~s, ~s, ~s, ~p, ~p, ?MODULE);\n\n", 			 [ImplM, ImplF, CallArgs, State, Context, UseThis, UseFrom,			  Precond, Postcond])	    end    end;emit_skel_func_helper(G, N, X, OpName, ArgNames, _TypeList, OutArgs, Oneway,		      _Backend) ->    Fd = ic_genobj:stubfiled(G),    Name	= list_to_atom(OpName),    ImplF	= Name,    ImplM	= list_to_atom(ic_genobj:impl(G)),    FromStr	= mk_name(G, "From"),    State	= mk_name(G, "State"),    %% Create argument list    CallArgs1 = [State | ArgNames],    {CallArgs2, From} =	case is_oneway(X) of	    false ->		case use_from(G, N, OpName) of		    true ->			{[FromStr | CallArgs1], FromStr};		    false ->			{CallArgs1, "_"}		end;	    true ->		{CallArgs1, "_"}	end,    %% Create argument list string    CallArgs = mk_list(CallArgs2),    emit_op_comment(G, Fd, X, Name, ArgNames, OutArgs),    FunName = case ic_options:get_opt(G, scoped_op_calls) of 		  true -> 		      list_to_atom(ic_util:to_undersc([OpName | N]));		  false ->		      list_to_atom(OpName)	      end,    case Oneway of	true ->	    if		length(ArgNames) == 0 ->		    emit(Fd, "handle_cast(~p, ~s) ->\n", [FunName, State]);		true ->		    emit(Fd, "handle_cast({~p, ~s}, ~s) ->\n",			 [FunName, mk_list(ArgNames), State])	    end,	    emit(Fd, "    ~p:~p(~s);\n\n", [ImplM, ImplF, CallArgs]);	false ->	    if		length(ArgNames) == 0 ->		    emit(Fd, "handle_call(~p, ~s, ~s) ->\n",			 [FunName, From, State]);		true ->		    emit(Fd, "handle_call({~p, ~s}, ~s, ~s) ->\n",  			 [FunName, mk_list(ArgNames), From, State])	    end,	    emit(Fd, "    ~p:~p(~s);\n\n", [ImplM, ImplF, CallArgs])    end.use_this(G, N, OpName) ->    FullOp = ic_util:to_colon([OpName|N]),    FullIntf = ic_util:to_colon(N),    case {get_opt(G, {this, FullIntf}), get_opt(G, {this, FullOp}), 	  get_opt(G, {this, true})} of	{_, force_false, _} -> false;	{force_false, false, _} -> false;	{false, false, false} -> false;	_ -> true    end.use_from(G, N, OpName) ->    FullOp = ic_util:to_colon([OpName|N]),    FullIntf = ic_util:to_colon(N),    case {get_opt(G, {from, FullIntf}), get_opt(G, {from, FullOp}), 	  get_opt(G, {from, true})} of	{_, force_false, _} -> false;	{force_false, false, _} -> false;	{false, false, false} -> false;	_ -> true    end.emit_constant_func(G, Id, Val) ->    case ic_genobj:is_stubfile_open(G) of	false -> ok;	true ->	    Fd = ic_genobj:stubfiled(G),	    N = list_to_atom(get_id(Id)),	    emit_const_comment(G, Fd, Id, N),	    emit(Fd, "~p() -> ~p.\n\n", [N, Val])    end.emit_const_comment(_G, F, _X, Name) ->    ic_codegen:mcomment_light(F,			 [io_lib:format("Constant: ~p", [Name])]).emit_op_comment(G, F, X, Name, InP, OutP) ->    ic_codegen:mcomment_light(F,			 [io_lib:format("~s: ~p", [get_title(X), Name]),			  "",			  get_returns(G, X, InP, OutP) |			  get_raises(X)]).get_title(X) when record(X, attr) -> "Attribute Operation";get_title(_X) -> "Operation".get_raises(X) when record(X, op) ->    if  X#op.raises == [] -> [];	true ->	    ["  Raises:  " ++ 	     mk_list(lists:map(fun(E) -> ic_util:to_colon(E) end, 			       X#op.raises))]    end;get_raises(_X) -> [].get_returns(_G, _X, _InP, []) ->    "  Returns: RetVal";get_returns(G, _X, _InP, OutP) ->    "  Returns: "++mk_list(["RetVal" | mk_erl_vars(G, OutP)]).%%------------------------------------------------------------%%%% Utilities%%%% Convenient little go-get functions%%%%------------------------------------------------------------%% The automaticly generated get and set operation names for an%% attribute.mk_attr_func_names(_Scope, Name) ->    {"_get_" ++ Name, "_set_" ++ Name}.%%    {scoped_name(Scope, "_get_"++Name), scoped_name(Scope, "_set_"++Name)}.%% Returns TK of the Get and Set attribute functions.mk_attr_func_types(_N, X) ->    TK = ic_forms:get_tk(X),    {{TK, [], []}, {tk_void, [TK], []}}.        %%------------------------------------------------------------%%%% Generation utilities and common stuff%%%% Convenient stuff for generation%%%%------------------------------------------------------------%% Input is a list of parameters (in parse form) and output is a list%% of capitalised variable names. mk_var is in icgenmk_erl_vars(_G, Params) ->    map(fun(P) -> mk_var(get_id(P#param.id)) end, Params).%% mk_list produces a nice comma separated string of variable namesmk_list([]) -> [];mk_list([Arg | Args]) ->    Arg ++ mk_list2(Args).mk_list2([Arg | Args]) ->    ", " ++ Arg ++ mk_list2(Args);mk_list2([]) -> [].%%------------------------------------------------------------%%%% Parser utilities%%%% Called from the yecc parser. Expands the identifier list of an%% attribute so that the attribute generator never has to handle%% lists.%%%%------------------------------------------------------------%% Unfold identifier lists or nested lists. Note that many records%% contain an entry named id that is a list before unfold and a single%% id afterwards.unfold(L) when list(L) ->    lists:flatten(map(fun(X) -> unfold2(X) end, L));unfold(X) -> unfold2(X).    unfold2(A) when record(A, attr) ->    map(fun(Id) -> A#attr{id=Id} end, A#attr.id);unfold2(M) when record(M, member) ->    map(fun(Id) -> M#member{id=Id} end, M#member.id);unfold2(M) when record(M, case_dcl) ->    map(fun(Id) -> M#case_dcl{label=Id} end, M#case_dcl.label);unfold2(T) when record(T, typedef) ->    map(fun(Id) -> T#typedef{id=Id} end, T#typedef.id).%% Code produce for dependency functiongenDependency(G) ->    Fd = ic_genobj:stubfiled(G),    nl(Fd),nl(Fd),    ic_codegen:comment(Fd, "Idl file dependency list function"),     emit(Fd, "oe_dependency() ->\n\n", []),    emit(Fd, "    ~p.\n\n", [ic_pragma:get_dependencies(G)]).   

⌨️ 快捷键说明

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