Skip to content

Commit

Permalink
stdlib: put more descriptive values for cached data in edlin_type_sug…
Browse files Browse the repository at this point in the history
…gestion
  • Loading branch information
frazze-jobb committed Jan 9, 2025
1 parent bf2d5fd commit 251a98b
Showing 1 changed file with 36 additions and 32 deletions.
68 changes: 36 additions & 32 deletions lib/stdlib/src/edlin_type_suggestion.erl
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ type_tree(Mod, FunType, Nestings, FT) ->
%% a new result should be calculated. Preferably only types that depend on the table
%% would be invalidated, but it may turn advanced.
%% TODO look this over to make sure we don't do unnecessary work,
case get({type_traverser, Mod, FunType, Nestings}) of
case get({?MODULE, type_traverser, Mod, FunType, Nestings}) of
undefined -> Res = type_traverser_cache(Mod, FunType, #{}, length(Nestings)+1, FT),
put({type_traverser, Mod, FunType, Nestings}, Res),
put({?MODULE, type_traverser, Mod, FunType, Nestings}, Res),
Res;
Res -> Res
end.
type_traverser_cache(Mod, T, Visited, Level, FT) ->
case get({Mod, T, Level}) of
case get({?MODULE, type_traverser_intermediate_result, Mod, T, Level}) of
undefined ->
Res = type_traverser(Mod, T, Visited, Level, FT),
put({Mod, T, Level}, Res),
put({?MODULE, type_traverser_intermediate_result, Mod, T, Level}, Res),
Res;
Res -> Res
end.
Expand Down Expand Up @@ -123,13 +123,13 @@ type_traverser(_, {remote_type,_,[{_,_,Mod},{_,_,Name}, Params]}=T, Visited, Lev
type_traverser(Mod, {user_type,_,Name,Params}=T, Visited, 1=Level, FT) ->
case maps:is_key(strip_anno(T), Visited) of
false ->
case get({strip_anno(T), 1}) of
case get({?MODULE, type_traverser_intermediate_result, strip_anno(T), 1}) of
undefined ->
Res = case lookup_type(Mod, Name, length(Params), FT) of
hidden -> {type, Mod, Name, [type_traverser(Mod, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params]};
Type -> {user_type, Mod, Name, [type_traverser(Mod, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params], type_traverser(Mod, Type, Visited#{ strip_anno(T) => true }, Level, FT)}
end,
put({strip_anno(T), 1}, Res),
put({?MODULE, type_traverser_intermediate_result, strip_anno(T), 1}, Res),
Res;
Res -> Res
end;
Expand All @@ -138,13 +138,13 @@ type_traverser(Mod, {user_type,_,Name,Params}=T, Visited, 1=Level, FT) ->
type_traverser(_, {remote_type,_,[{_,_,Mod},{_,_,Name}, Params]}=T, Visited, 1=Level, FT) ->
case maps:is_key(strip_anno(T), Visited) of
false ->
case get({strip_anno(T), 1}) of
case get({?MODULE, type_traverser_intermediate_result, strip_anno(T), 1}) of
undefined ->
Res = case lookup_type(Mod, Name, length(Params), FT) of
hidden -> {type, Mod, Name, [type_traverser(Mod, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params]};
Type -> {user_type, Mod, Name, [type_traverser(Mod, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params], type_traverser(Mod, Type, Visited#{ strip_anno(T) => true }, Level, FT)}
end,
put({strip_anno(T), 1}, Res),
put({?MODULE, type_traverser_intermediate_result, strip_anno(T), 1}, Res),
Res;
Res -> Res
end;
Expand All @@ -153,13 +153,13 @@ type_traverser(_, {remote_type,_,[{_,_,Mod},{_,_,Name}, Params]}=T, Visited, 1=L
type_traverser(Mod, {user_type,_,Name,Params}=T, Visited, Level, FT) ->
case maps:is_key(strip_anno(T), Visited) of
false ->
case get({strip_anno(T), Level}) of
case get({?MODULE, type_traverser_intermediate_result, strip_anno(T), Level}) of
undefined ->
Res = case lookup_type(Mod, Name, length(Params), FT) of
hidden -> {type, Mod, Name, [type_traverser(Mod, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params]};
Type -> type_traverser(Mod, Type, Visited#{ strip_anno(T) => true }, Level, FT)
end,
put({strip_anno(T), Level}, Res),
put({?MODULE, type_traverser_intermediate_result, strip_anno(T), Level}, Res),
Res;
Res -> Res
end;
Expand All @@ -168,13 +168,13 @@ type_traverser(Mod, {user_type,_,Name,Params}=T, Visited, Level, FT) ->
type_traverser(_, {remote_type, _, [{_,_,Mod},{_,_,Name}, Params]}=T, Visited, Level, FT) ->
case maps:is_key(strip_anno(T), Visited) of
false ->
case get({strip_anno(T), Level}) of
case get({?MODULE, type_traverser_intermediate_result, strip_anno(T), Level}) of
undefined ->
Res = case lookup_type(Mod, Name, length(Params), FT) of
hidden -> {type, Mod, Name, [type_traverser(Mod, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params]};
Type -> type_traverser(Mod, Type, Visited#{ strip_anno(T) => true }, Level, FT)
end,
put({strip_anno(T), Level}, Res),
put({?MODULE, type_traverser_intermediate_result, strip_anno(T), Level}, Res),
Res;
Res -> Res
end;
Expand All @@ -193,13 +193,13 @@ type_traverser(_, {type, _, term, _}, _, _, _) ->
type_traverser(_, {type, _, Name, Params}=T, Visited, Level, FT) ->
case maps:is_key(strip_anno(T), Visited) of
false ->
case get({strip_anno(T), 1}) of
case get({?MODULE, type_traverser_intermediate_result, strip_anno(T), 1}) of
undefined ->
Res = case lookup_type(erlang, Name, length(Params), FT) of
hidden -> {type, Name, [type_traverser(erlang, P, Visited#{ strip_anno(T) => true }, Level, FT) || P <- Params]};
Type -> type_traverser(erlang, Type, Visited#{ strip_anno(T) => true}, Level, FT)
end,
put({strip_anno(T), 1}, Res),
put({?MODULE, type_traverser_intermediate_result, strip_anno(T), 1}, Res),
Res;
Res -> Res
end;
Expand All @@ -221,19 +221,28 @@ simplified_type(file, name, 0) -> {type, erlang, string, []};
simplified_type(_Module, _TypeName, _Arity) -> none.

code_get_doc_cache(Mod) ->
case get(Mod) of
case get({?MODULE, module_debug_info_doc, Mod}) of
undefined ->
Docs = code:get_doc(Mod, #{sources => [debug_info]}),
put(Mod, Docs),
Docs;
case code:get_doc(Mod, #{sources => [debug_info]}) of
{ok, #docs_v1{ docs = Docs }} ->
put({?MODULE, module_debug_info_doc, Mod}, Docs),
Docs;
_ -> put({?MODULE, module_debug_info_doc, Mod}, none),
none
end;
Docs -> Docs
end.

lookup_type(Mod, Type, Arity, FT) ->
case simplified_type(Mod, Type, Arity) of
none ->
case code_get_doc_cache(Mod) of
{ok, #docs_v1{ docs = Docs } } ->
none ->
case [TypeAST || {{type, Type2}, {attribute,_,type,{_,TypeAST,_}}} <- FT, Type2 =:= Type] of
[] -> hidden; %% can be an opaque type or missing type
[SingleTypeAST] -> SingleTypeAST
end;
Docs ->
FnFunctions =
lists:filter(fun({{type, T, A},_Anno,_Sig,_Doc,_Meta}) ->
T =:= Type andalso A =:= Arity;
Expand All @@ -247,18 +256,17 @@ lookup_type(Mod, Type, Arity, FT) ->
[SingleTypeAST] -> SingleTypeAST
end;
[{_,_,_,_,#{signature := [{attribute,_,type,{_,TypeAST,_}}]}}] -> TypeAST
end;
_ ->
case [TypeAST || {{type, Type2}, {attribute,_,type,{_,TypeAST,_}}} <- FT, Type2 =:= Type] of
[] -> hidden; %% can be an opaque type or missing type
[SingleTypeAST] -> SingleTypeAST
end
end;
T -> T
end.
get_function_type(Mod, Fun, Arity, FT) ->
case code:get_doc(Mod, #{sources => [debug_info]}) of
{ok, #docs_v1{ docs = Docs } } ->
case code_get_doc_cache(Mod) of
none when Mod =:= shell_default ->
lists:flatten([FunTypes || {{function_type, {shell_default, F, A}},{attribute,_,spec,{_,FunTypes}}} <- FT,
F =:= Fun, A =:= Arity]);
none -> [];
Docs ->
R = lists:flatten([FunTypes ||
{{function, F, A},_Anno,_Sig,_Doc, #{ signature := [{attribute,_,spec,{_,FunTypes}}]}} <- Docs,
F =:= Fun, A =:= Arity]),
Expand All @@ -267,12 +275,8 @@ get_function_type(Mod, Fun, Arity, FT) ->
lists:flatten([FunTypes ||
{{function_type, {shell_default, F, A}},{attribute,_,spec,{_,FunTypes}}} <- FT,
F =:= Fun, A =:= Arity]);
_ -> R
end;
_ when Mod =:= shell_default ->
lists:flatten([FunTypes || {{function_type, {shell_default, F, A}},{attribute,_,spec,{_,FunTypes}}} <- FT,
F =:= Fun, A =:= Arity]);
_ -> []
_ -> R
end
end.
get_arity(Constraints, Type, Nestings) ->
case get_arity1(Type, Constraints, Nestings) of
Expand Down

0 comments on commit 251a98b

Please sign in to comment.