%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1999-2009. All Rights Reserved. %% %% 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 online 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. %% %% %CopyrightEnd% %% %% -module(ic_java_type). -include("icforms.hrl"). -include("ic.hrl"). -include("ic_debug.hrl"). %%----------------------------------------------------------------- %% External exports %%----------------------------------------------------------------- -export([getType/3, getHolderType/3, getParamType/4, inlinedTypes/2, marshalFun/4, unMarshalFun/4, getFullType/4, getFullType/3, getMarshalType/4, getUnmarshalType/4, getdim/1]). -export([isBasicType/3, isBasicType/1]). -export([isIntegerType/3, isIntegerType/1]). -export([isTermType/3]). %%----------------------------------------------------------------- %% Internal exports %%----------------------------------------------------------------- -export([]). %%----------------------------------------------------------------- %% External functions %%----------------------------------------------------------------- %%----------------------------------------------------------------- %% Func: getType/3 %%----------------------------------------------------------------- getType(G, N, T) when is_record(T, scoped_id) -> {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), case BT of "erlang.pid" -> ?ICPACKAGE ++ "Pid"; "erlang.port" -> ?ICPACKAGE ++ "Port"; "erlang.ref" -> ?ICPACKAGE ++ "Ref"; "erlang.term" -> ?ICPACKAGE ++ "Term"; {enum, Type} -> getType(G, N, Type); Type -> case TK of {tk_array,_,_} -> tk2type(G,N,T,TK); {tk_sequence,_,_} -> tk2type(G,N,T,TK); tk_any -> ?ICPACKAGE ++ "Any"; _ -> case isBasicType(G,N,TK) of true -> tk2type(G,N,T,TK); false -> Type %% Other types end end end; getType(_G, _N, S) when is_list(S) -> S; getType(_G, _N, T) when is_record(T, string) -> "java.lang.String"; getType(_G, _N, T) when is_record(T, wstring) -> %% WSTRING "java.lang.String"; getType(G, N, T) when is_record(T, struct) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]); getType(G, N, T) when is_record(T, union) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]); getType(G, N, T) when is_record(T, sequence) -> getType(G, N, ic_forms:get_type(T)) ++ "[]"; getType(G, N, T) when is_record(T, enum) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]); %% NOTE i am using the new isJavaElementaryType %% to avoid members declared as keywords (except %% all java elementary types) to be used as a %% class getType(G, N, T) when is_record(T, member) -> Type = tk2type(G,N,T,ic_forms:get_type_code(G, N, T)), case isJavaElementaryType(list_to_atom(Type)) of true -> Type; false -> Prefix = list_to_atom(lists:flatten(string:tokens(Type,"[]"))), case isJavaElementaryType(Prefix) of %% Checks if Type is an array %% of elementary java types true -> Type; false -> ic_forms:get_java_id(getType(G,N,ic_forms:get_type(T))) ++ if is_record(hd(T#member.id),array) -> arrayEmptyDim(hd(T#member.id)); true -> "" end end end; getType(_G, _N, {boolean, _}) -> "boolean"; getType(_G, _N, {octet, _}) -> "byte"; getType(_G, _N, {void, _}) -> "void"; getType(_G, _N, {unsigned, U}) -> case U of {short,_} -> "short"; {long,_} -> "int"; {'long long',_} -> "long" end; getType(_G, _N, {char, _}) -> "char"; getType(_G, _N, {wchar, _}) -> %% WCHAR "char"; getType(_G, _N, {short, _}) -> "short"; getType(_G, _N, {long, _}) -> "int"; getType(_G, _N, {'long long', _}) -> "long"; getType(_G, _N, {float, _}) -> "float"; getType(_G, _N, {double, _}) -> "double"; getType(_G, _N, {any, _}) -> ?ICPACKAGE ++ "Any". %%----------------------------------------------------------------- %% Func: getHolderType/3 %%----------------------------------------------------------------- getHolderType(G, N, T) when element(1, T) == scoped_id -> {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), case BT of "erlang.pid" -> ?ICPACKAGE ++ "PidHolder"; "erlang.port" -> ?ICPACKAGE ++ "PortHolder"; "erlang.ref" -> ?ICPACKAGE ++ "RefHolder"; "erlang.term" -> ?ICPACKAGE ++ "TermHolder"; {enum, Type} -> getHolderType(G, N, Type); Type -> case TK of {'tk_struct', _, _, _} -> Type ++ "Holder"; {'tk_union', _, _, _, _, _} -> Type ++ "Holder"; {'tk_array', _ , _} -> Type ++ "Holder"; {'tk_sequence', _ , _} -> Type ++ "Holder"; {'tk_string', _} -> ?ICPACKAGE ++ "StringHolder"; {'tk_wstring', _} -> %% WSTRING ?ICPACKAGE ++ "StringHolder"; {'tk_enum', _, _, _} -> Type ++ "Holder"; 'tk_boolean' -> ?ICPACKAGE ++ "BooleanHolder"; 'tk_octet' -> ?ICPACKAGE ++ "ByteHolder"; 'tk_ushort' -> ?ICPACKAGE ++ "ShortHolder"; 'tk_ulong' -> ?ICPACKAGE ++ "IntHolder"; 'tk_ulonglong' -> %% ULLONG ?ICPACKAGE ++ "LongHolder"; 'tk_short' -> ?ICPACKAGE ++ "ShortHolder"; 'tk_long' -> ?ICPACKAGE ++ "IntHolder"; 'tk_longlong' -> ?ICPACKAGE ++ "LongHolder"; %% LLONG 'tk_float' -> ?ICPACKAGE ++ "FloatHolder"; 'tk_double' -> ?ICPACKAGE ++ "DoubleHolder"; 'tk_char' -> ?ICPACKAGE ++ "CharHolder"; 'tk_wchar' -> %% WCHAR ?ICPACKAGE ++ "CharHolder"; 'tk_any' -> ?ICPACKAGE ++ "AnyHolder"; _ -> case isBasicType(G,N,TK) of true -> %% Faked the type ! getHolderType(G, N, {list_to_atom(tk2type(G,N,T,TK)), -1}); false -> %%io:format("TK = ~p, Type = ~p\n",[TK,Type]), ic_util:to_dot(G,FullScopedName) ++ "Holder" end end end; getHolderType(G, N, S) when is_list(S) -> ic_util:to_dot(G,[S|N]) ++ "Holder"; getHolderType(_G, _N, T) when is_record(T, string) -> ?ICPACKAGE ++"StringHolder"; getHolderType(_G, _N, T) when is_record(T, wstring) -> %% WSTRING ?ICPACKAGE ++"StringHolder"; getHolderType(G, N, T) when is_record(T, struct) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; getHolderType(G, N, T) when is_record(T, union) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; getHolderType(G, N, T) when is_record(T, array) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; getHolderType(G, N, T) when is_record(T, sequence) -> getType(G, N, ic_forms:get_type(T)) ++ "Holder[]"; getHolderType(G, N, T) when is_record(T, enum) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Holder"; getHolderType(_G, _N, {boolean, _}) -> ?ICPACKAGE ++"BooleanHolder"; getHolderType(_G, _N, {octet, _}) -> ?ICPACKAGE ++"ByteHolder"; getHolderType(_G, _N, {void, _}) -> "void"; getHolderType(_G, _N, {unsigned, U}) -> case U of {short,_} -> ?ICPACKAGE ++"ShortHolder"; {long,_} -> ?ICPACKAGE ++"IntHolder"; {'long long',_} -> ?ICPACKAGE ++"LongHolder" end; getHolderType(_G, _N, {char, _}) -> ?ICPACKAGE ++"CharHolder"; getHolderType(_G, _N, {wchar, _}) -> %% WCHAR ?ICPACKAGE ++"CharHolder"; getHolderType(_G, _N, {short, _}) -> ?ICPACKAGE ++"ShortHolder"; getHolderType(_G, _N, {long, _}) -> ?ICPACKAGE ++"IntHolder"; getHolderType(_G, _N, {'long long', _}) -> ?ICPACKAGE ++"LongHolder"; getHolderType(_G, _N, {float, _}) -> ?ICPACKAGE ++"FloatHolder"; getHolderType(_G, _N, {double, _}) -> ?ICPACKAGE ++"DoubleHolder"; getHolderType(_G, _N, {any,_}) -> ?ICPACKAGE ++ "AnyHolder". %%----------------------------------------------------------------- %% Func: getParamType/4 %%----------------------------------------------------------------- getParamType(G, N, S, in) -> getType(G, N, S); getParamType(G, N, S, ret) -> getType(G, N, S); getParamType(G, N, S, out) -> getHolderType(G, N, S); getParamType(G, N, S, inout) -> getHolderType(G, N, S). %%----------------------------------------------------------------- %% Func: getUnmarshalType/4 %%----------------------------------------------------------------- getUnmarshalType(G, N, X, T) when element(1, T) == scoped_id -> {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), case BT of "erlang.pid" -> ?ICPACKAGE ++ "PidHelper"; "erlang.port" -> ?ICPACKAGE ++ "PortHelper"; "erlang.ref" -> ?ICPACKAGE ++ "RefHelper"; "erlang.term" -> ?ICPACKAGE ++ "TermHelper"; {enum, Type} -> getUnmarshalType(G, N, X, Type); Type -> case TK of {'tk_struct', _, _, _} -> Type ++ "Helper"; {'tk_union', _, _, _, _, _} -> Type ++ "Helper"; {'tk_sequence', _ , _} -> Type ++ "Helper"; {'tk_array', _ , _} -> Type ++ "Helper"; {'tk_enum', _, _, _} -> Type ++ "Helper"; {'tk_string',_} -> ?ERLANGPACKAGE ++ "OtpErlangString"; {'tk_wstring',_} -> %% WSTRING ?ERLANGPACKAGE ++ "OtpErlangString"; 'tk_char' -> ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_wchar' -> %% WCHAR ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_octet' -> ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_ushort' -> ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_ulong' -> ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_ulonglong' -> %% ULLONG ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_short' -> ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_long' -> ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_longlong' -> %% LLONG ?ERLANGPACKAGE ++ "OtpErlangLong"; 'tk_float' -> ?ERLANGPACKAGE ++ "OtpErlangDouble"; 'tk_double' -> ?ERLANGPACKAGE ++ "OtpErlangDouble"; 'tk_boolean' -> ?ERLANGPACKAGE ++ "OtpErlangAtom"; 'tk_void' -> ?ERLANGPACKAGE ++ "OtpErlangAtom"; 'tk_any' -> ?ICPACKAGE ++ "AnyHelper"; _ -> case isBasicType(G,N,TK) of true -> %% Faked the type ! getUnmarshalType(G, N, X, {list_to_atom(tk2type(G,N,T,TK)), -1}); false -> ic_util:to_dot(G,FullScopedName) ++ "Helper" end end end; getUnmarshalType(_G, _N, _X, S) when is_list(S) -> S ++ "Helper"; getUnmarshalType(_G, _N, _X, T) when is_record(T, string) -> ?ERLANGPACKAGE ++ "OtpErlangString"; getUnmarshalType(_G, _N, _X, T) when is_record(T, wstring) -> %% WSTRING ?ERLANGPACKAGE ++ "OtpErlangString"; getUnmarshalType(G, N, _X, T) when is_record(T, struct) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getUnmarshalType(G, N, _X, T) when is_record(T, union) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getUnmarshalType(G, N, X, T) when is_record(T, sequence) andalso is_record(X, member) -> ic_util:to_dot(G,[ic_forms:get_id2(X)|N]) ++ "Helper"; getUnmarshalType(G, N, X, T) when is_record(T, sequence) andalso is_record(X, case_dcl) -> ic_util:to_dot(G,[ic_forms:get_id2(X)|N]) ++ "Helper"; getUnmarshalType(G, N, X, T) when is_record(T, sequence) -> getUnmarshalType(G, N, X, ic_forms:get_type(T)) ++ "Helper"; getUnmarshalType(G, N, X, T) when is_record(T, array) andalso is_record(X, case_dcl) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getUnmarshalType(G, N, _X, T) when is_record(T, enum) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getUnmarshalType(_G, _N, _X, {boolean, _}) -> ?ERLANGPACKAGE ++ "OtpErlangAtom"; getUnmarshalType(_G, _N, _X, {octet, _}) -> ?ERLANGPACKAGE ++ "OtpErlangLong"; getUnmarshalType(_G, _N, _X, {void, _}) -> ?ERLANGPACKAGE ++ "OtpErlangAtom"; getUnmarshalType(_G, _N, _X, {unsigned, U}) -> case U of {short,_} -> ?ERLANGPACKAGE ++ "OtpErlangLong"; {long,_} -> ?ERLANGPACKAGE ++ "OtpErlangLong"; {'long long',_} -> ?ERLANGPACKAGE ++ "OtpErlangLong" end; getUnmarshalType(_G, _N, _X, {char, _}) -> ?ERLANGPACKAGE ++ "OtpErlangLong"; getUnmarshalType(_G, _N, _X, {wchar, _}) -> %% WCHAR ?ERLANGPACKAGE ++ "OtpErlangLong"; getUnmarshalType(_G, _N, _X, {short, _}) -> ?ERLANGPACKAGE ++ "OtpErlangLong"; getUnmarshalType(_G, _N, _X, {long, _}) -> ?ERLANGPACKAGE ++ "OtpErlangLong"; getUnmarshalType(_G, _N, _X, {'long long', _}) -> ?ERLANGPACKAGE ++ "OtpErlangLong"; getUnmarshalType(_G, _N, _X, {float, _}) -> ?ERLANGPACKAGE ++ "OtpErlangDouble"; getUnmarshalType(_G, _N, _X, {double, _}) -> ?ERLANGPACKAGE ++ "OtpErlangDouble"; getUnmarshalType(_G, _N, _X, {any, _}) -> ?ICPACKAGE ++ "AnyHelper". %%----------------------------------------------------------------- %% Func: getMarshalType/4 %%----------------------------------------------------------------- getMarshalType(G, N, X, T) when element(1, T) == scoped_id -> {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), case BT of "erlang.pid" -> ?ICPACKAGE ++ "PidHelper"; "erlang.port" -> ?ICPACKAGE ++ "PortHelper"; "erlang.ref" -> ?ICPACKAGE ++ "RefHelper"; "erlang.term" -> ?ICPACKAGE ++ "TermHelper"; {enum, Type} -> getMarshalType(G, N, X, Type); Type -> case TK of {'tk_struct', _, _, _} -> Type ++ "Helper"; {'tk_union', _, _, _, _, _} -> Type ++ "Helper"; {'tk_array', _ , _} -> Type ++ "Helper"; {'tk_sequence', _ , _} -> Type ++ "Helper"; {'tk_enum', _, _, _} -> Type ++ "Helper"; {'tk_string',_} -> "string"; {'tk_wstring',_} -> %% WSTRING "string"; 'tk_char' -> "char"; 'tk_wchar' -> %% WCHAR "char"; 'tk_octet' -> "byte"; 'tk_ushort' -> "ushort"; 'tk_ulong' -> "uint"; 'tk_ulonglong' -> %% ULLONG "ulong"; 'tk_short' -> "short"; 'tk_long' -> "int"; 'tk_longlong' -> %% LLONG "long"; 'tk_float' -> "float"; 'tk_double' -> "double"; 'tk_boolean' -> "boolean"; 'tk_void' -> "atom"; 'tk_any' -> ?ICPACKAGE ++ "AnyHelper"; _ -> case isBasicType(G,N,TK) of true -> %% Faked the type ! getMarshalType(G, N, X, {list_to_atom(tk2type(G,N,T,TK)), -1}); false -> ic_util:to_dot(G,FullScopedName) ++ "Helper" end end end; getMarshalType(_G, _N, _X, S) when is_list(S) -> S ++ "Helper"; getMarshalType(_G, _N, _X, T) when is_record(T, string) -> "string"; getMarshalType(_G, _N, _X, T) when is_record(T, wstring) -> %% WSTRING "string"; getMarshalType(G, N, _X, T) when is_record(T, struct) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getMarshalType(G, N, _X, T) when is_record(T, union) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getMarshalType(G, N, X, T) when is_record(T, array) andalso is_record(X, case_dcl) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getMarshalType(G, N, X, T) when is_record(T, sequence) andalso is_record(X, member) -> ic_util:to_dot(G,[ic_forms:get_id2(X)|N]) ++ "Helper"; getMarshalType(G, N, _X, T) when is_record(T, sequence) -> getType(G, N, ic_forms:get_type(T)) ++ "Helper"; getMarshalType(G, N, _X, T) when is_record(T, enum) -> ic_util:to_dot(G,[ic_forms:get_id2(T)|N]) ++ "Helper"; getMarshalType(_G, _N, _X, {boolean, _}) -> "boolean"; getMarshalType(_G, _N, _X, {octet, _}) -> "byte"; getMarshalType(_G, _N, _X, {void, _}) -> ""; % <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< getMarshalType(_G, _N, _X, {unsigned, U}) -> case U of {short,_} -> "ushort"; {long,_} -> "uint"; {'long long',_} -> "ulong" end; getMarshalType(_G, _N, _X, {short, _}) -> "short"; getMarshalType(_G, _N, _X, {long, _}) -> "int"; getMarshalType(_G, _N, _X, {'long long', _}) -> "long"; getMarshalType(_G, _N, _X, {float, _}) -> "float"; getMarshalType(_G, _N, _X, {double, _}) -> "double"; getMarshalType(_G, _N, _X, {char, _}) -> "char"; getMarshalType(_G, _N, _X, {wchar, _}) -> %% WCHAR "char"; getMarshalType(_G, _N, _X, {any, _}) -> ?ICPACKAGE ++ "AnyHelper". %%----------------------------------------------------------------- %% Func: unMarshalFun/4 %%----------------------------------------------------------------- unMarshalFun(G, N, X, T) when element(1, T) == scoped_id -> {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), BT = ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)), case BT of "erlang.pid" -> ".read_pid()"; "erlang.port" -> ".read_port()"; "erlang.ref" -> ".read_ref()"; "erlang.term" -> ".read_term()"; {enum, Type} -> unMarshalFun(G, N, X, Type); _Type -> case isBasicType(G,N,TK) of true -> case TK of {'tk_string',_} -> ".read_string()"; {'tk_wstring',_} -> %% WSTRING ".read_string()"; 'tk_boolean' -> ".read_boolean()"; 'tk_octet' -> ".read_byte()"; 'tk_ushort' -> ".read_ushort()"; 'tk_ulong' -> ".read_uint()"; 'tk_ulonglong' -> %% ULLONG ".read_ulong()"; 'tk_short' -> ".read_short()"; 'tk_long' -> ".read_int()"; 'tk_longlong' -> %% LLONG ".read_long()"; 'tk_float' -> ".read_float()"; 'tk_double' -> ".read_double()"; 'tk_char' -> ".read_char()"; 'tk_wchar' -> %% WCHAR ".read_char()"; _ -> %% Faked the type ! unMarshalFun(G, N, X, {list_to_atom(tk2type(G,N,X,TK)), -1}) end; false -> ".unmarshal()" end end; unMarshalFun(_G, _N, _X, S) when is_list(S) -> ".unmarshal()"; unMarshalFun(_G, _N, _X, T) when is_record(T, string) -> ".read_string()"; unMarshalFun(_G, _N, _X, T) when is_record(T, wstring) -> %% WSTRING ".read_string()"; unMarshalFun(_G, _N, _X, T) when is_record(T, struct) -> ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlangTuple)"; unMarshalFun(_G, _N, _X, T) when is_record(T, union) -> ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlangTuple)"; unMarshalFun(_G, _N, _X, T) when is_record(T, sequence) -> ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlanglist)"; unMarshalFun(_G, _N, _X, T) when is_record(T, enum) -> ".unmarshal((" ++ ?ERLANGPACKAGE ++ "OtpErlangAtom)"; unMarshalFun(_G, _N, _X, {boolean, _}) -> ".read_boolean()"; unMarshalFun(_G, _N, _X, {octet, _}) -> ".read_byte()"; unMarshalFun(_G, _N, _X, {void, _}) -> ""; unMarshalFun(_G, _N, _X, {unsigned, U}) -> case U of {short,_} -> ".read_ushort()"; {long,_} -> ".read_uint()"; {'long long',_} -> ".read_ulong()" end; unMarshalFun(_G, _N, _X, {short, _}) -> ".read_short()"; unMarshalFun(_G, _N, _X, {long, _}) -> ".read_int()"; unMarshalFun(_G, _N, _X, {'long long', _}) -> ".read_long()"; unMarshalFun(_G, _N, _X, {float, _}) -> ".read_float()"; unMarshalFun(_G, _N, _X, {double, _}) -> ".read_double()"; unMarshalFun(_G, _N, _X, {char, _}) -> ".read_char()"; unMarshalFun(_G, _N, _X, {wchar, _}) -> %% WCHAR ".read_char()". %%----------------------------------------------------------------- %% Func: getFullType/4 - /3 %% %% Note : Similar to the getType/3 with the major difference %% thet on arrays and sequences it will also declare %% their sizes. Used for "new" declarations %% %%----------------------------------------------------------------- getFullType(G, N, X, T) when is_record(X, typedef) andalso is_record(T, array) -> FullDim = tk2FullType(G,N,X,ic_forms:get_tk(X)) ++ getFullDim(G,N,T#array.size), fixArrayDims(FullDim); getFullType(G, N, X, T) when is_record(X, member) andalso is_record(T, array) -> FullDim = getFullType(G, N, ic_forms:get_type(X)) ++ getFullDim(G,N,T#array.size), fixArrayDims(FullDim); getFullType(G, N, X, T) when is_record(X, case_dcl) andalso is_record(T, array) -> FullDim = getFullType(G, N, ic_forms:get_type(X)) ++ getFullDim(G,N,T#array.size), fixArrayDims(FullDim); getFullType(G, N, _X, T) -> getFullType(G, N, T). getFullType(G, N, T) when is_record(T, scoped_id) -> {FullScopedName, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, T), case TK of {tk_array,_,_} -> tk2FullType(G,N,T,TK); {tk_sequence,_,_} -> tk2FullType(G,N,T,TK); _ -> case isBasicType(G,N,TK) of true -> tk2FullType(G,N,T,TK); false -> %% Other types ic_code:get_basetype(G, ic_util:to_dot(G,FullScopedName)) end end; getFullType(G, N, T) when is_record(T, sequence) -> fixSeqDims(getType(G,N,T),"_length"); getFullType(G, N, T) -> getType(G, N, T). %% In order to make a legal declaration %% of an assignable array, the dimensions %% of empty array sequences are swifted to %% the end of the type fixArrayDims(Cs) -> fixArrayDims(Cs,[],[]). fixArrayDims([],Fulls,Emptys) -> lists:reverse(Fulls) ++ Emptys; fixArrayDims([91,93|Rest],Fulls,Emptys) -> fixArrayDims(Rest,Fulls,[91,93|Emptys]); fixArrayDims([C|Rest],Fulls,Emptys) -> fixArrayDims(Rest,[C|Fulls],Emptys). %% In order to make a legal declaration %% of an assignable array, the dimensions %% of empty array of sequences are swifted %% to the end of the type fixSeqDims(Cs,Length) -> fixSeqDims(Cs,Length,[]). fixSeqDims([],_Length,Found) -> lists:reverse(Found); fixSeqDims([91,93|Rest],Length,Found) when is_list(Length) -> lists:reverse([93|lists:reverse(Length)] ++ [91|Found]) ++ Rest; fixSeqDims([C|Rest],Length,Found) -> fixSeqDims(Rest,Length,[C|Found]). %%----------------------------------------------------------------- %% Func: inlinedTypes/2 %%----------------------------------------------------------------- inlinedTypes(PkgName, Type) when is_record(Type, struct) -> "_" ++ PkgName ++ "."; inlinedTypes(PkgName, Type) when is_record(Type, union) -> "_" ++ PkgName ++ "."; inlinedTypes(PkgName, Type) when is_record(Type, enum) -> "_" ++ PkgName ++ "."; inlinedTypes(_, _) -> "". %%----------------------------------------------------------------- %% Func: marshalFun/4 %%----------------------------------------------------------------- marshalFun(G, N, X, Type) -> case isBasicType(G, N, Type) of true -> ".write_" ++ getMarshalType(G, N, X, Type); _ -> getMarshalType(G, N, X, Type) ++ ".marshal" end. %%----------------------------------------------------------------- %% Func: isBasicType/3 %%----------------------------------------------------------------- isBasicType(G, N, S) when element(1, S) == scoped_id -> {_, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, S), isBasicType(ictype:fetchType(TK)); isBasicType(G, N, X) when is_record(X, member) -> if is_record(hd(element(3,X)), array) -> false; true -> isBasicType(G, N, element(2,X)) end; isBasicType(_G, _N, {unsigned, {long, _}} ) -> true; isBasicType(_G, _N, {unsigned, {short, _}} ) -> true; isBasicType(_G, _N, {unsigned, {'long long', _}} ) -> true; isBasicType(_G, _N, {'long long', _} ) -> true; isBasicType(_G, _N, {Type, _} ) -> isBasicType(Type); isBasicType(_G, _N, Type) -> isBasicType(Type). %%----------------------------------------------------------------- %% Func: isBasicType/1 %%----------------------------------------------------------------- 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_wstring,wstring, %% WSTRING tk_string,string]). %% returns true if the Type is a java elementary type isJavaElementaryType( Type ) -> lists:member(Type, [byte, char, wchar, boolean, int, short, long, 'long long', float, double]). %%----------------------------------------------------------------- %% Func: isIntegerType/3 %%----------------------------------------------------------------- isIntegerType(G, N, S) when element(1, S) == scoped_id -> {_, _, TK, _} = ic_symtab:get_full_scoped_name(G, N, S), isIntegerType(ictype:fetchType(TK)); isIntegerType(_G, _N, {unsigned, {long, _}} ) -> true; isIntegerType(_G, _N, {unsigned, {short, _}} ) -> true; isIntegerType(_G, _N, {unsigned, {'long long', _}} ) -> true; isIntegerType(_G, _N, {'long long', _} ) -> true; isIntegerType(_G, _N, {Type, _} ) -> isIntegerType(Type); isIntegerType(_G, _N, Type) -> isIntegerType(Type). %%----------------------------------------------------------------- %% Func: isIntegerType/1 %%----------------------------------------------------------------- isIntegerType( 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_char,char, tk_wchar,wchar, %% WCHAR tk_octet,octet]). %%----------------------------------------------------------------- %% Func: isTerm/3 %%----------------------------------------------------------------- isTermType(G, N, T) -> case getType(G,N,T) of "com.ericsson.otp.ic.Term" -> true; _ -> false end. %%----------------------------------------------------------------- %% Internal functions %%----------------------------------------------------------------- %% Changes the typecode to the %% corresponding "basic" type tk2type(_G,_N,_X,{'tk_struct', _IFRId, "port", _ElementList}) -> ?ICPACKAGE ++ "Port"; tk2type(_G,_N,_X,{'tk_struct', _IFRId, "pid", _ElementList}) -> ?ICPACKAGE ++ "Pid"; tk2type(_G,_N,_X,{'tk_struct', _IFRId, "ref", _ElementList}) -> ?ICPACKAGE ++ "Ref"; tk2type(_G,_N,_X,{'tk_struct', _IFRId, "term", _ElementList}) -> ?ICPACKAGE ++ "Term"; tk2type(_G,_N,_X,{'tk_string', _}) -> "java.lang.String"; tk2type(_G,_N,_X,{'tk_wstring', _}) -> %% WSTRING "java.lang.String"; tk2type(G,N,X,{'tk_array', ElemTC, Dim}) -> tkarr2decl(G,N,X,{'tk_array', ElemTC, Dim}); tk2type(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}) -> tkseq2decl(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}); tk2type(G,N,_X,{'tk_struct', IFRId, Name, _ElementList}) -> ScopedId= lists:reverse(string:tokens(lists:nth(2,string:tokens(IFRId,":")),"/")), case ic_forms:clean_up_scope([Name|N]) of ScopedId -> %% Right path, use N instead ic_util:to_dot(G,[Name|N]); _ -> %% Ugly work arround ic_util:to_dot(G,ScopedId) end; tk2type(G,N,_X,{'tk_union', IFRId, Name, _, _, _ElementList}) -> ScopedId= lists:reverse(string:tokens(lists:nth(2,string:tokens(IFRId,":")),"/")), case ic_forms:clean_up_scope([Name|N]) of ScopedId -> %% Right path, use N instead ic_util:to_dot(G,[Name|N]); _ -> %% Ugly work arround ic_util:to_dot(G,ScopedId) end; tk2type(_G,_N,_X,{'tk_enum', _Id, Name, _ElementList}) -> Name; tk2type(_G,_N,_X,tk_void) -> "void"; tk2type(_G,_N,_X,tk_long) -> "int"; tk2type(_G,_N,_X,tk_longlong) -> %% LLONG "long"; tk2type(_G,_N,_X,tk_short) -> "short"; tk2type(_G,_N,_X,tk_ulong) -> "int"; tk2type(_G,_N,_X,tk_ulonglong) -> %% ULLONG "long"; tk2type(_G,_N,_X,tk_ushort) -> "short"; tk2type(_G,_N,_X,tk_float) -> "float"; tk2type(_G,_N,_X,tk_double) -> "double"; tk2type(_G,_N,_X,tk_boolean) -> "boolean"; tk2type(_G,_N,_X,tk_char) -> "char"; tk2type(_G,_N,_X,tk_wchar) -> %% WCHAR "char"; tk2type(_G,_N,_X,tk_octet) -> "byte"; tk2type(_G,_N,_X,tk_string) -> "java.lang.String"; tk2type(_G,_N,_X,tk_wstring) -> %% WSTRING "java.lang.String"; tk2type(_G,_N,_X,tk_any) -> ?ICPACKAGE ++ "Any"; tk2type(_G,_N,_X,tk_term) -> %% Term ?ICPACKAGE ++ "Term". %% Changes the sequence typecode to the %% corresponding "basic" structure tkseq2decl(G,N,X,TKSeq) -> tkseq2decl2(G,N,X,TKSeq,[],[]). tkseq2decl2(G,N,X,{tk_sequence,E,D},[],Ds) -> tkseq2decl2(G,N,X,E,[],[D|Ds]); tkseq2decl2(G,N,X,TkEl,[],Ds) -> ElName = tk2type(G,N,X,TkEl), ElName ++ getdim(Ds). %% Changes the array typecode to the %% corresponding "basic" structure tkarr2decl(G,N,X,TKArr) -> tkarr2decl2(G,N,X,TKArr,[],[]). tkarr2decl2(G,N,X,{tk_array,E,D},[],Ds) -> tkarr2decl2(G,N,X,E,[],[D|Ds]); tkarr2decl2(G,N,X,TkEl,[],Ds) -> ElName = tk2type(G,N,X,TkEl), ElName ++ getdim(Ds). getdim([]) -> ""; getdim([_D|Ds]) -> getdim(Ds) ++ "[]". %% Changes the typecode to the corresponding "basic" type %% used for variable declarations where arrays and sequences %% are declared with there full dimensions tk2FullType(G,N,X,{'tk_array', ElemTC, Dim}) -> tkarr2FullDecl(G,N,X,{'tk_array', ElemTC, Dim}); tk2FullType(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}) -> tkseq2FullDecl(G,N,X,{'tk_sequence', ElemTC, MaxLsextractength}); tk2FullType(G,N,X,TK) -> tk2type(G,N,X,TK). %% Changes the sequence typecode to the %% corresponding "basic" structure here %% arrays and sequences are declared with %% their full dimensions tkseq2FullDecl(G,N,X,TKSeq) -> tkseq2FullDecl2(G,N,X,TKSeq,[],[]). tkseq2FullDecl2(G,N,X,{tk_sequence,E,D},[],Ds) -> tkseq2FullDecl2(G,N,X,E,[],[D|Ds]); tkseq2FullDecl2(G,N,X,TkEl,[],Ds) -> ElName = tk2FullType(G,N,X,TkEl), ElName ++ getdim(Ds). %% Changes the array typecode to the %% corresponding "basic" structure tkarr2FullDecl(G,N,X,TKArr) -> tkarr2FullDecl2(G,N,X,TKArr,[],[]). tkarr2FullDecl2(G,N,X,{tk_array,E,D},[],Ds) -> tkarr2FullDecl2(G,N,X,E,[],[D|Ds]); tkarr2FullDecl2(G,N,X,TkEl,[],Ds) -> ElName = tk2FullType(G,N,X,TkEl), ElName ++ getFullDim(G,N,Ds). getFullDim(_G,_N,[]) -> ""; getFullDim(G,N,[D|Ds]) when is_record(D,scoped_id) -> {FSN, _, _, _} = ic_symtab:get_full_scoped_name(G, N, D), "[" ++ ic_util:to_dot(G,FSN) ++ "]" ++ getFullDim(G,N,Ds); getFullDim(G,N,[D|Ds]) when is_integer(D) -> "[" ++ integer_to_list(D) ++ "]" ++ getFullDim(G,N,Ds); getFullDim(G,N,[D|Ds]) when is_tuple(D) -> "[" ++ ic_util:eval_java(G,N,D) ++ "]" ++ getFullDim(G,N,Ds). %% Constructs an array empty dimension string %% used for array variable declaration arrayEmptyDim(X) -> arrayEmptyDim2(X#array.size). arrayEmptyDim2([_D]) -> "[]"; arrayEmptyDim2([_D |Ds]) -> "[]" ++ arrayEmptyDim2(Ds).