34
35:- module(codewalk_prolog, []). 36
37:- use_module(library(lists)). 38:- use_module(library(option)). 39:- use_module(library(prolog_codewalk)). 40:- use_module(library(assertions)). 41:- use_module(library(extra_location)). 42:- use_module(library(option_utils)). 43:- use_module(library(from_utils)). 44:- init_expansors. 45
46:- thread_local
47 issues/1.
51extra_walk_module_body(Options) :-
52 ( option(module(M), Options)
53 ->findall(Ref, current_clause_module_body(M, Ref), RefU),
54 sort(RefU, RefL),
55 prolog_walk_code([source(false), clauses(RefL)|Options])
56 ; true
57 ).
58
59:- multifile
60 codewalk:walk_code/2. 61
62codewalk:walk_code(prolog, Options1) :-
63 extra_wcsetup(Options1, Options2, MFileD),
64 foldl(select_option_default,
65 [source(S)-false,
66 walkextras(Extras)-[declaration, asrparts([body])],
67 on_trace(ETracer)-ETracer
68 ], Options2, Options3),
69 Options = [on_trace(codewalk_prolog:pcw_trace(1, ETracer, MFileD))|Options3],
70 extra_walk_module_body(Options),
71 optimized_walk_code(S, Stage, codewalk_prolog:pcw_trace(Stage, ETracer, MFileD), Options3),
72 prolog_codewalk:make_walk_option(Options, OTerm),
73 maplist(walk_extras_p(OTerm, MFileD), Extras).
74
75:- public pcw_trace/6. 76:- meta_predicate pcw_trace(+,3,+,+,+,+). 77pcw_trace(1, ETracer, MFileD, M:Goal, Caller, From) :-
78 get_dict(M, MFileD, FileD),
79 from_to_file(From, File),
80 get_dict(File, FileD, _),
81 '$set_source_module'(M),
82 call(ETracer, M:Goal, Caller, From),
83 ( From = clause(CRef)
84 ->record_issues(CRef)
85 ; true
86 ).
87pcw_trace(2, ETracer, _, Goal, Caller, From) :-
88 call(ETracer, Goal, Caller, From).
89
(OTerm, MFileD, Extra) :- walk_extras_(Extra, OTerm, MFileD).
91
(declaration, OTerm, MFileD) :- walk_from_loc_declaration(OTerm, MFileD).
93walk_extras_(asrparts(L), OTerm, MFileD) :- walk_from_assertion(OTerm, MFileD, L).
94
95current_clause_module_body(CM, Ref) :-
96 MH = M:_,
97 current_predicate(_, MH),
98 M \= CM,
99 \+ predicate_property(MH, imported_from(_)),
100 ( catch(clause(MH, Body, Ref), _, fail),
101 clause_property(Ref, module(HM)),
102 strip_module(HM:Body, CM, _)
103 ).
104
105optimized_walk_code(false, 1, Tracer, Options) :-
106 prolog_walk_code([source(false), on_trace(Tracer)|Options]).
107optimized_walk_code(true, Stage, Tracer, Options) :-
108 optimized_walk_code_true(Stage, Tracer, Options).
109
110optimized_walk_code_true(1, Tracer, Options) :-
111 prolog_walk_code([source(false), on_trace(Tracer)|Options]),
112 fail.
113optimized_walk_code_true(2, Tracer, Options) :-
114 findall(CRef, retract(issues(CRef)), ClausesU),
115 sort(ClausesU, Clauses),
116 ( Clauses==[]
117 ->true
118 ; prolog_walk_code([clauses(Clauses), on_trace(Tracer)|Options])
119 ).
120
(Options1, Options, MFileD) :-
122 option_module_files(MFileD, Options1, Options2),
123 merge_options(Options2,
124 [infer_meta_predicates(false),
125 autoload(false),
126 evaluate(false),
127 trace_reference(_),
128 module_class([user, system, library])
129 ], Options).
130
131walk_from_loc_declaration(OTerm, MFileD) :-
132 forall(( prolog_codewalk:walk_option_caller(OTerm, '<declaration>'),
133 clause(loc_declaration(Head, M, goal, From), _, Ref),
134 get_dict(M, MFileD, FileD),
135 from_to_file(From, File),
136 get_dict(File, FileD, _)
137 ),
138 walk_from_goal(Head, M, Ref, OTerm)).
139
140walk_from_goal(Head, M, Ref, OTerm) :-
141 prolog_codewalk:( scan_module(M, OTerm),
142 walk_option_clause(OTerm, Ref),
143 walk_called_by_body(no_positions, Head, M, OTerm)
144 ).
145
146walk_from_assertion(OTerm, MFileD, AsrPartL) :-
147 option_files([module_files(MFileD)], FileD),
148 forall(( AHead = assertions:asr_head_prop(Asr, HM, Head, _, _, _, _, From),
149 clause(AHead, Body, Ref),
150 module_property(Ref, module(M)),
151 call(M:Body),
152 from_to_file(From, File),
153 get_dict(File, FileD, _),
154 predicate_property(HM:Head, implementation_module(M)),
155 prolog_codewalk:walk_option_caller(OTerm, '<assertion>'(M:Head)),
156 member(AsrPart, AsrPartL),
157 assertion_goal(AsrPart, Head, HM, Asr, Goal, CM)
158 ),
159 walk_from_goal(Goal, CM, Ref, OTerm)).
160
161assertion_goal(head, Head, HM, _, Head, HM).
162assertion_goal(body, _, _, Asr, Prop, PM) :-
163 member(Part, [comp, call, succ, glob]),
164 165 curr_prop_asr(Part, PM:Prop, _, Asr).
166
167record_issues(CRef) :-
168 assertz(issues(CRef))