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