14
15:- module(util_for_graphML, [
16 predicate_in_file/4,
17 file_of_predicate/4,
18 main_module_of_file/2,
19 first_line_of_predicate_in_file/5,
20 exported_predicate/3,
21 exported_predicate/2,
22 locally_dead_predicate/3,
23 call_term_position/7
24]). 25
26:- use_module(library(lists)). 27:- use_module(pdt_prolog_library(utils4modules_visibility)). 28:- use_module(pdt_common_pl('callgraph/pdt_call_graph')). 29:- use_module(pdt_prolog_library(compatibility), [
30 pdt_source_file/2
31]). 32
33predicate_in_file(File, Module, Name, Arity) :-
34 pdt_source_file(Module:Head, File),
35 functor(Head, Name, Arity),
36 \+ find_blacklist(Name, Arity, Module).
37
38find_blacklist('$load_context_module',2,_).
39find_blacklist('$load_context_module',3,_).
40find_blacklist('$mode',2,_).
41find_blacklist('$pldoc',4,_).
42
43
44file_of_predicate(Module, Name, Arity, File) :-
45 functor(Head, Name, Arity),
46 ( predicate_property(Module:Head, multifile)
47 -> defined_in_files(Module, Name, Arity, Locations),
48 member(File-_, Locations)
49 ; ( predicate_property(Module:Head, file(File))
50 -> true
51 ; module_property(Module, file(File))
52 )
53 ).
54
55main_module_of_file(File, Module) :-
56 module_property(Module, File),
57 \+ atom_concat(plunit_, _, Module),
58 !.
59
60main_module_of_file(_File, user).
61
62first_line_of_predicate_in_file(Module, Name, Arity, File, Line) :-
63 functor(Head, Name, Arity),
64 ( predicate_property(Module:Head, multifile)
65 -> defined_in_files(Module, Name, Arity, Locations),
66 member(File-LineAndRefs, Locations),
67 findall(L, member(location(L, _), LineAndRefs), Ls),
68 min_list(Ls, Line)
69 ; ( predicate_property(Module:Head, line_count(Line))
70 -> true
71 ; Line = 1
72 )
73 ).
74
75
76exported_predicate(Module, Name, Arity) :-
77 functor(Head, Name, Arity),
78 exported_predicate(Module, Head).
79
80exported_predicate(Module, Head) :-
81 ( Module == user
82 ; predicate_property(Module:Head, exported)
83 ),
84 !.
85
86locally_dead_predicate(Module, Name, Arity) :-
87 locally_dead_predicate(Module, Name, Arity, [Module:Name/Arity]).
88
89locally_dead_predicate(Module, Name, Arity, _Visited):-
90 uncalled_local_predicate(Module, Name, Arity).
91locally_dead_predicate(Module, Name, Arity, Visited):-
92 \+ exported_predicate(Module, Name, Arity),
93 forall((
94 calls(Module, Name, Arity, CallerModule, CallerName, CallerArity, _NumberOfCalls),
95 \+ member(CallerModule:CallerName/CallerArity, Visited)
96 ),(
97 locally_dead_predicate(CallerModule, CallerName, CallerArity, [CallerModule:CallerName/CallerArity | Visited])
98 )).
99
100uncalled_local_predicate(Module, Name, Arity):-
101 uncalled_predicate(Module, Name, Arity),
102 \+ exported_predicate(Module, Name, Arity).
103
104uncalled_predicate(Module, Name, Arity):-
105 declared_in_module(Module, Name, Arity, _),
106 \+ calls(Module, Name, Arity, _, _, _, _).
107
108assert_location(_, _, clause_term_position(_Ref, TermPosition), _) :-
109 asserta(location(TermPosition)).
110
111:- dynamic(location/1). 112
113call_term_position(SourceModule, SourceFunctor, SourceArity, TargetModule, TargetFunctor, TargetArity, Position) :-
114 retractall(location(_)),
115 functor(Target, TargetFunctor, TargetArity),
116 pdt_walk_code([trace_reference(TargetModule:Target), predicates([SourceModule:SourceFunctor/SourceArity]), on_trace(util_for_graphML:assert_location)]),
117 location(TermPosition),
118 !,
119 ( TermPosition = term_position(Start, End, _, _, _)
120 ; TermPosition = Start-End
121 ),
122 format(atom(Position), '~w-~w', [Start, End])