36
37:- module(prolog_xref,
38 [ xref_source/1, 39 xref_source/2, 40 xref_called/3, 41 xref_called/4, 42 xref_defined/3, 43 xref_definition_line/2, 44 xref_exported/2, 45 xref_module/2, 46 xref_uses_file/3, 47 xref_op/2, 48 xref_prolog_flag/4, 49 xref_comment/3, 50 xref_comment/4, 51 xref_mode/3, 52 xref_option/2, 53 xref_clean/1, 54 xref_current_source/1, 55 xref_done/2, 56 xref_built_in/1, 57 xref_source_file/3, 58 xref_source_file/4, 59 xref_public_list/3, 60 xref_public_list/4, 61 xref_public_list/6, 62 xref_public_list/7, 63 xref_meta/3, 64 xref_meta/2, 65 xref_hook/1, 66 67 xref_used_class/2, 68 xref_defined_class/3 69 ]). 70:- use_module(library(debug), [debug/3]). 71:- use_module(library(lists), [append/3, append/2, member/2, select/3]). 72:- use_module(library(operators), [push_op/3]). 73:- use_module(library(shlib), [current_foreign_library/2]). 74:- use_module(library(ordsets)). 75:- use_module(library(prolog_source)). 76:- use_module(library(option)). 77:- use_module(library(error)). 78:- use_module(library(apply)). 79:- use_module(library(debug)). 80:- if(exists_source(library(pldoc))). 81:- use_module(library(pldoc), []). 82:- use_module(library(pldoc/doc_process)). 83:- endif. 84:- use_module(library(solution_sequences)). 85:- use_module(library(modules)). 86
87:- predicate_options(xref_source/2, 2,
88 [ silent(boolean),
89 module(atom),
90 register_called(oneof([all,non_iso,non_built_in])),
91 comments(oneof([store,collect,ignore])),
92 process_include(boolean)
93 ]). 94
95
96:- dynamic
97 called/4, 98 (dynamic)/3, 99 (thread_local)/3, 100 (multifile)/3, 101 (public)/3, 102 defined/3, 103 meta_goal/3, 104 foreign/3, 105 constraint/3, 106 imported/3, 107 exported/2, 108 xmodule/2, 109 uses_file/3, 110 xop/2, 111 source/2, 112 used_class/2, 113 defined_class/5, 114 (mode)/2, 115 xoption/2, 116 xflag/4, 117
118 module_comment/3, 119 pred_comment/4, 120 pred_comment_link/3, 121 pred_mode/3. 122
123:- create_prolog_flag(xref, false, [type(boolean)]). 124
140
141:- predicate_options(xref_source_file/4, 4,
142 [ file_type(oneof([txt,prolog,directory])),
143 silent(boolean)
144 ]). 145:- predicate_options(xref_public_list/3, 3,
146 [ path(-atom),
147 module(-atom),
148 exports(-list(any)),
149 public(-list(any)),
150 meta(-list(any)),
151 silent(boolean)
152 ]). 153
154
155 158
165
173
178
183
184:- multifile
185 prolog:called_by/4, 186 prolog:called_by/2, 187 prolog:meta_goal/2, 188 prolog:hook/1, 189 prolog:generated_predicate/1. 190
191:- meta_predicate
192 prolog:generated_predicate(:). 193
194:- dynamic
195 meta_goal/2. 196
197:- meta_predicate
198 process_predicates(2, +, +). 199
200 203
209
210hide_called(Callable, Src) :-
211 xoption(Src, register_called(Which)),
212 !,
213 mode_hide_called(Which, Callable).
214hide_called(Callable, _) :-
215 mode_hide_called(non_built_in, Callable).
216
217mode_hide_called(all, _) :- !, fail.
218mode_hide_called(non_iso, _:Goal) :-
219 goal_name_arity(Goal, Name, Arity),
220 current_predicate(system:Name/Arity),
221 predicate_property(system:Goal, iso).
222mode_hide_called(non_built_in, _:Goal) :-
223 goal_name_arity(Goal, Name, Arity),
224 current_predicate(system:Name/Arity),
225 predicate_property(system:Goal, built_in).
226mode_hide_called(non_built_in, M:Goal) :-
227 goal_name_arity(Goal, Name, Arity),
228 current_predicate(M:Name/Arity),
229 predicate_property(M:Goal, built_in).
230
234
235system_predicate(Goal) :-
236 goal_name_arity(Goal, Name, Arity),
237 current_predicate(system:Name/Arity), 238 predicate_property(system:Goal, built_in),
239 !.
240
241
242 245
246verbose(Src) :-
247 \+ xoption(Src, silent(true)).
248
249:- thread_local
250 xref_input/2. 251
252
277
278xref_source(Source) :-
279 xref_source(Source, []).
280
281xref_source(Source, Options) :-
282 prolog_canonical_source(Source, Src),
283 ( last_modified(Source, Modified)
284 -> ( source(Src, Modified)
285 -> true
286 ; xref_clean(Src),
287 assert(source(Src, Modified)),
288 do_xref(Src, Options)
289 )
290 ; xref_clean(Src),
291 get_time(Now),
292 assert(source(Src, Now)),
293 do_xref(Src, Options)
294 ).
295
296do_xref(Src, Options) :-
297 must_be(list, Options),
298 setup_call_cleanup(
299 xref_setup(Src, In, Options, State),
300 collect(Src, Src, In, Options),
301 xref_cleanup(State)).
302
303last_modified(Source, Modified) :-
304 prolog:xref_source_time(Source, Modified),
305 !.
306last_modified(Source, Modified) :-
307 atom(Source),
308 \+ is_global_url(Source),
309 exists_file(Source),
310 time_file(Source, Modified).
311
312is_global_url(File) :-
313 sub_atom(File, B, _, _, '://'),
314 !,
315 B > 1,
316 sub_atom(File, 0, B, _, Scheme),
317 atom_codes(Scheme, Codes),
318 maplist(between(0'a, 0'z), Codes).
319
320xref_setup(Src, In, Options, state(In, Dialect, Xref, [SRef|HRefs])) :-
321 maplist(assert_option(Src), Options),
322 assert_default_options(Src),
323 current_prolog_flag(emulated_dialect, Dialect),
324 prolog_open_source(Src, In),
325 set_initial_mode(In, Options),
326 asserta(xref_input(Src, In), SRef),
327 set_xref(Xref),
328 ( verbose(Src)
329 -> HRefs = []
330 ; asserta(user:thread_message_hook(_,_,_), Ref),
331 HRefs = [Ref]
332 ).
333
334assert_option(_, Var) :-
335 var(Var),
336 !,
337 instantiation_error(Var).
338assert_option(Src, silent(Boolean)) :-
339 !,
340 must_be(boolean, Boolean),
341 assert(xoption(Src, silent(Boolean))).
342assert_option(Src, register_called(Which)) :-
343 !,
344 must_be(oneof([all,non_iso,non_built_in]), Which),
345 assert(xoption(Src, register_called(Which))).
346assert_option(Src, comments(CommentHandling)) :-
347 !,
348 must_be(oneof([store,collect,ignore]), CommentHandling),
349 assert(xoption(Src, comments(CommentHandling))).
350assert_option(Src, module(Module)) :-
351 !,
352 must_be(atom, Module),
353 assert(xoption(Src, module(Module))).
354assert_option(Src, process_include(Boolean)) :-
355 !,
356 must_be(boolean, Boolean),
357 assert(xoption(Src, process_include(Boolean))).
358
359assert_default_options(Src) :-
360 ( xref_option_default(Opt),
361 generalise_term(Opt, Gen),
362 ( xoption(Src, Gen)
363 -> true
364 ; assertz(xoption(Src, Opt))
365 ),
366 fail
367 ; true
368 ).
369
370xref_option_default(silent(false)).
371xref_option_default(register_called(non_built_in)).
372xref_option_default(comments(collect)).
373xref_option_default(process_include(true)).
374
378
379xref_cleanup(state(In, Dialect, Xref, Refs)) :-
380 prolog_close_source(In),
381 set_prolog_flag(emulated_dialect, Dialect),
382 set_prolog_flag(xref, Xref),
383 maplist(erase, Refs).
384
385set_xref(Xref) :-
386 current_prolog_flag(xref, Xref),
387 set_prolog_flag(xref, true).
388
395
396set_initial_mode(_Stream, Options) :-
397 option(module(Module), Options),
398 !,
399 '$set_source_module'(Module).
400set_initial_mode(Stream, _) :-
401 stream_property(Stream, file_name(Path)),
402 source_file_property(Path, load_context(M, _, Opts)),
403 !,
404 '$set_source_module'(M),
405 ( option(dialect(Dialect), Opts)
406 -> expects_dialect(Dialect)
407 ; true
408 ).
409set_initial_mode(_, _) :-
410 '$set_source_module'(user).
411
415
416xref_input_stream(Stream) :-
417 xref_input(_, Var),
418 !,
419 Stream = Var.
420
425
426xref_push_op(Src, P, T, N0) :-
427 '$current_source_module'(M0),
428 strip_module(M0:N0, M, N),
429 ( is_list(N),
430 N \== []
431 -> maplist(push_op(Src, P, T, M), N)
432 ; push_op(Src, P, T, M, N)
433 ).
434
435push_op(Src, P, T, M0, N0) :-
436 strip_module(M0:N0, M, N),
437 Name = M:N,
438 valid_op(op(P,T,Name)),
439 push_op(P, T, Name),
440 assert_op(Src, op(P,T,Name)),
441 debug(xref(op), ':- ~w.', [op(P,T,Name)]).
442
443valid_op(op(P,T,M:N)) :-
444 atom(M),
445 valid_op_name(N),
446 integer(P),
447 between(0, 1200, P),
448 atom(T),
449 op_type(T).
450
451valid_op_name(N) :-
452 atom(N),
453 !.
454valid_op_name(N) :-
455 N == [].
456
457op_type(xf).
458op_type(yf).
459op_type(fx).
460op_type(fy).
461op_type(xfx).
462op_type(xfy).
463op_type(yfx).
464
468
469xref_set_prolog_flag(Flag, Value, Src, Line) :-
470 atom(Flag),
471 !,
472 assertz(xflag(Flag, Value, Src, Line)).
473xref_set_prolog_flag(_, _, _, _).
474
478
479xref_clean(Source) :-
480 prolog_canonical_source(Source, Src),
481 retractall(called(_, Src, _Origin, _Cond)),
482 retractall(dynamic(_, Src, Line)),
483 retractall(multifile(_, Src, Line)),
484 retractall(public(_, Src, Line)),
485 retractall(defined(_, Src, Line)),
486 retractall(meta_goal(_, _, Src)),
487 retractall(foreign(_, Src, Line)),
488 retractall(constraint(_, Src, Line)),
489 retractall(imported(_, Src, _From)),
490 retractall(exported(_, Src)),
491 retractall(uses_file(_, Src, _)),
492 retractall(xmodule(_, Src)),
493 retractall(xop(Src, _)),
494 retractall(xoption(Src, _)),
495 retractall(xflag(_Name, _Value, Src, Line)),
496 retractall(source(Src, _)),
497 retractall(used_class(_, Src)),
498 retractall(defined_class(_, _, _, Src, _)),
499 retractall(mode(_, Src)),
500 retractall(module_comment(Src, _, _)),
501 retractall(pred_comment(_, Src, _, _)),
502 retractall(pred_comment_link(_, Src, _)),
503 retractall(pred_mode(_, Src, _)).
504
505
506 509
513
514xref_current_source(Source) :-
515 source(Source, _Time).
516
517
521
522xref_done(Source, Time) :-
523 prolog_canonical_source(Source, Src),
524 source(Src, Time).
525
526
532
533xref_called(Source, Called, By) :-
534 xref_called(Source, Called, By, _).
535
536xref_called(Source, Called, By, Cond) :-
537 canonical_source(Source, Src),
538 called(Called, Src, By, Cond).
539
540
559
560xref_defined(Source, Called, How) :-
561 nonvar(Source),
562 !,
563 canonical_source(Source, Src),
564 xref_defined2(How, Src, Called).
565xref_defined(Source, Called, How) :-
566 xref_defined2(How, Src, Called),
567 canonical_source(Source, Src).
568
569xref_defined2(dynamic(Line), Src, Called) :-
570 dynamic(Called, Src, Line).
571xref_defined2(thread_local(Line), Src, Called) :-
572 thread_local(Called, Src, Line).
573xref_defined2(multifile(Line), Src, Called) :-
574 multifile(Called, Src, Line).
575xref_defined2(public(Line), Src, Called) :-
576 public(Called, Src, Line).
577xref_defined2(local(Line), Src, Called) :-
578 defined(Called, Src, Line).
579xref_defined2(foreign(Line), Src, Called) :-
580 foreign(Called, Src, Line).
581xref_defined2(constraint(Line), Src, Called) :-
582 constraint(Called, Src, Line).
583xref_defined2(imported(From), Src, Called) :-
584 imported(Called, Src, From).
585
586
591
592xref_definition_line(local(Line), Line).
593xref_definition_line(dynamic(Line), Line).
594xref_definition_line(thread_local(Line), Line).
595xref_definition_line(multifile(Line), Line).
596xref_definition_line(public(Line), Line).
597xref_definition_line(constraint(Line), Line).
598xref_definition_line(foreign(Line), Line).
599
600
604
605xref_exported(Source, Called) :-
606 prolog_canonical_source(Source, Src),
607 exported(Called, Src).
608
612
613xref_module(Source, Module) :-
614 nonvar(Source),
615 !,
616 prolog_canonical_source(Source, Src),
617 xmodule(Module, Src).
618xref_module(Source, Module) :-
619 xmodule(Module, Src),
620 prolog_canonical_source(Source, Src).
621
629
630xref_uses_file(Source, Spec, Path) :-
631 prolog_canonical_source(Source, Src),
632 uses_file(Spec, Src, Path).
633
641
642xref_op(Source, Op) :-
643 prolog_canonical_source(Source, Src),
644 xop(Src, Op).
645
651
652xref_prolog_flag(Source, Flag, Value, Line) :-
653 prolog_canonical_source(Source, Src),
654 xflag(Flag, Value, Src, Line).
655
656xref_built_in(Head) :-
657 system_predicate(Head).
658
659xref_used_class(Source, Class) :-
660 prolog_canonical_source(Source, Src),
661 used_class(Class, Src).
662
663xref_defined_class(Source, Class, local(Line, Super, Summary)) :-
664 prolog_canonical_source(Source, Src),
665 defined_class(Class, Super, Summary, Src, Line),
666 integer(Line),
667 !.
668xref_defined_class(Source, Class, file(File)) :-
669 prolog_canonical_source(Source, Src),
670 defined_class(Class, _, _, Src, file(File)).
671
672:- thread_local
673 current_cond/1,
674 source_line/1. 675
676current_source_line(Line) :-
677 source_line(Var),
678 !,
679 Line = Var.
680
686
687collect(Src, File, In, Options) :-
688 ( Src == File
689 -> SrcSpec = Line
690 ; SrcSpec = (File:Line)
691 ),
692 option(comments(CommentHandling), Options, collect),
693 ( CommentHandling == ignore
694 -> CommentOptions = [],
695 Comments = []
696 ; CommentHandling == store
697 -> CommentOptions = [ process_comment(true) ],
698 Comments = []
699 ; CommentOptions = [ comments(Comments) ]
700 ),
701 repeat,
702 catch(prolog_read_source_term(
703 In, Term, Expanded,
704 [ term_position(TermPos)
705 | CommentOptions
706 ]),
707 E, report_syntax_error(E, Src, [])),
708 update_condition(Term),
709 stream_position_data(line_count, TermPos, Line),
710 setup_call_cleanup(
711 asserta(source_line(SrcSpec), Ref),
712 catch(process(Expanded, Comments, TermPos, Src, EOF),
713 E, print_message(error, E)),
714 erase(Ref)),
715 EOF == true,
716 !.
717
718report_syntax_error(E, _, _) :-
719 fatal_error(E),
720 throw(E).
721report_syntax_error(_, _, Options) :-
722 option(silent(true), Options),
723 !,
724 fail.
725report_syntax_error(E, Src, _Options) :-
726 ( verbose(Src)
727 -> print_message(error, E)
728 ; true
729 ),
730 fail.
731
732fatal_error(time_limit_exceeded).
733fatal_error(error(resource_error(_),_)).
734
738
739update_condition((:-Directive)) :-
740 !,
741 update_cond(Directive).
742update_condition(_).
743
744update_cond(if(Cond)) :-
745 !,
746 asserta(current_cond(Cond)).
747update_cond(else) :-
748 retract(current_cond(C0)),
749 !,
750 assert(current_cond(\+C0)).
751update_cond(elif(Cond)) :-
752 retract(current_cond(C0)),
753 !,
754 assert(current_cond((\+C0,Cond))).
755update_cond(endif) :-
756 retract(current_cond(_)),
757 !.
758update_cond(_).
759
764
765current_condition(Condition) :-
766 \+ current_cond(_),
767 !,
768 Condition = true.
769current_condition(Condition) :-
770 findall(C, current_cond(C), List),
771 list_to_conj(List, Condition).
772
773list_to_conj([], true).
774list_to_conj([C], C) :- !.
775list_to_conj([H|T], (H,C)) :-
776 list_to_conj(T, C).
777
778
779 782
792
793process(Expanded, Comments, TermPos, Src, EOF) :-
794 is_list(Expanded), 795 !,
796 ( member(Term, Expanded),
797 process(Term, Src),
798 Term == end_of_file
799 -> EOF = true
800 ; EOF = false
801 ),
802 xref_comments(Comments, TermPos, Src).
803process(end_of_file, _, _, _, true) :-
804 !.
805process(Term, Comments, TermPos, Src, false) :-
806 process(Term, Src),
807 xref_comments(Comments, TermPos, Src).
808
810
811process(Var, _) :-
812 var(Var),
813 !. 814process(end_of_file, _) :- !.
815process((:- Directive), Src) :-
816 !,
817 process_directive(Directive, Src),
818 !.
819process((?- Directive), Src) :-
820 !,
821 process_directive(Directive, Src),
822 !.
823process((Head :- Body), Src) :-
824 !,
825 assert_defined(Src, Head),
826 process_body(Body, Head, Src).
827process('$source_location'(_File, _Line):Clause, Src) :-
828 !,
829 process(Clause, Src).
830process(Term, Src) :-
831 process_chr(Term, Src),
832 !.
833process(M:(Head :- Body), Src) :-
834 !,
835 process((M:Head :- M:Body), Src).
836process(Head, Src) :-
837 assert_defined(Src, Head).
838
839
840 843
845
([], _Pos, _Src).
847:- if(current_predicate(parse_comment/3)). 848xref_comments([Pos-Comment|T], TermPos, Src) :-
849 ( Pos @> TermPos 850 -> true
851 ; stream_position_data(line_count, Pos, Line),
852 FilePos = Src:Line,
853 ( parse_comment(Comment, FilePos, Parsed)
854 -> assert_comments(Parsed, Src)
855 ; true
856 ),
857 xref_comments(T, TermPos, Src)
858 ).
859
([], _).
861assert_comments([H|T], Src) :-
862 assert_comment(H, Src),
863 assert_comments(T, Src).
864
(section(_Id, Title, Comment), Src) :-
866 assertz(module_comment(Src, Title, Comment)).
867assert_comment(predicate(PI, Summary, Comment), Src) :-
868 pi_to_head(PI, Src, Head),
869 assertz(pred_comment(Head, Src, Summary, Comment)).
870assert_comment(link(PI, PITo), Src) :-
871 pi_to_head(PI, Src, Head),
872 pi_to_head(PITo, Src, HeadTo),
873 assertz(pred_comment_link(Head, Src, HeadTo)).
874assert_comment(mode(Head, Det), Src) :-
875 assertz(pred_mode(Head, Src, Det)).
876
877pi_to_head(PI, Src, Head) :-
878 pi_to_head(PI, Head0),
879 ( Head0 = _:_
880 -> strip_module(Head0, M, Plain),
881 ( xmodule(M, Src)
882 -> Head = Plain
883 ; Head = M:Plain
884 )
885 ; Head = Head0
886 ).
887:- endif. 888
892
(Source, Title, Comment) :-
894 canonical_source(Source, Src),
895 module_comment(Src, Title, Comment).
896
900
(Source, Head, Summary, Comment) :-
902 canonical_source(Source, Src),
903 ( pred_comment(Head, Src, Summary, Comment)
904 ; pred_comment_link(Head, Src, HeadTo),
905 pred_comment(HeadTo, Src, Summary, Comment)
906 ).
907
912
913xref_mode(Source, Mode, Det) :-
914 canonical_source(Source, Src),
915 pred_mode(Mode, Src, Det).
916
921
922xref_option(Source, Option) :-
923 canonical_source(Source, Src),
924 xoption(Src, Option).
925
926
927 930
931process_directive(Var, _) :-
932 var(Var),
933 !. 934process_directive(Dir, _Src) :-
935 debug(xref(directive), 'Processing :- ~q', [Dir]),
936 fail.
937process_directive((A,B), Src) :- 938 !,
939 process_directive(A, Src), 940 process_directive(B, Src).
941process_directive(List, Src) :-
942 is_list(List),
943 !,
944 process_directive(consult(List), Src).
945process_directive(use_module(File, Import), Src) :-
946 process_use_module2(File, Import, Src, false).
947process_directive(expects_dialect(Dialect), Src) :-
948 process_directive(use_module(library(dialect/Dialect)), Src),
949 expects_dialect(Dialect).
950process_directive(reexport(File, Import), Src) :-
951 process_use_module2(File, Import, Src, true).
952process_directive(reexport(Modules), Src) :-
953 process_use_module(Modules, Src, true).
954process_directive(use_module(Modules), Src) :-
955 process_use_module(Modules, Src, false).
956process_directive(consult(Modules), Src) :-
957 process_use_module(Modules, Src, false).
958process_directive(ensure_loaded(Modules), Src) :-
959 process_use_module(Modules, Src, false).
960process_directive(load_files(Files, _Options), Src) :-
961 process_use_module(Files, Src, false).
962process_directive(include(Files), Src) :-
963 process_include(Files, Src).
964process_directive(dynamic(Dynamic), Src) :-
965 process_predicates(assert_dynamic, Dynamic, Src).
966process_directive(thread_local(Dynamic), Src) :-
967 process_predicates(assert_thread_local, Dynamic, Src).
968process_directive(multifile(Dynamic), Src) :-
969 process_predicates(assert_multifile, Dynamic, Src).
970process_directive(public(Public), Src) :-
971 process_predicates(assert_public, Public, Src).
972process_directive(export(Export), Src) :-
973 process_predicates(assert_export, Export, Src).
974process_directive(import(Import), Src) :-
975 process_import(Import, Src).
976process_directive(module(Module, Export), Src) :-
977 assert_module(Src, Module),
978 assert_module_export(Src, Export).
979process_directive(module(Module, Export, Import), Src) :-
980 assert_module(Src, Module),
981 assert_module_export(Src, Export),
982 assert_module3(Import, Src).
983process_directive('$set_source_module'(system), Src) :-
984 assert_module(Src, system). 985process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :-
986 assert_defined_class(Src, Name, Meta, Super, Doc).
987process_directive(pce_autoload(Name, From), Src) :-
988 assert_defined_class(Src, Name, imported_from(From)).
989
990process_directive(op(P, A, N), Src) :-
991 xref_push_op(Src, P, A, N).
992process_directive(set_prolog_flag(Flag, Value), Src) :-
993 ( Flag == character_escapes
994 -> set_prolog_flag(character_escapes, Value)
995 ; true
996 ),
997 current_source_line(Line),
998 xref_set_prolog_flag(Flag, Value, Src, Line).
999process_directive(style_check(X), _) :-
1000 style_check(X).
1001process_directive(encoding(Enc), _) :-
1002 ( xref_input_stream(Stream)
1003 -> catch(set_stream(Stream, encoding(Enc)), _, true)
1004 ; true 1005 ).
1006process_directive(pce_expansion:push_compile_operators, _) :-
1007 '$current_source_module'(SM),
1008 call(pce_expansion:push_compile_operators(SM)). 1009process_directive(pce_expansion:pop_compile_operators, _) :-
1010 call(pce_expansion:pop_compile_operators).
1011process_directive(meta_predicate(Meta), Src) :-
1012 process_meta_predicate(Meta, Src).
1013process_directive(arithmetic_function(FSpec), Src) :-
1014 arith_callable(FSpec, Goal),
1015 !,
1016 current_source_line(Line),
1017 assert_called(Src, '<directive>'(Line), Goal).
1018process_directive(format_predicate(_, Goal), Src) :-
1019 !,
1020 current_source_line(Line),
1021 assert_called(Src, '<directive>'(Line), Goal).
1022process_directive(if(Cond), Src) :-
1023 !,
1024 current_source_line(Line),
1025 assert_called(Src, '<directive>'(Line), Cond).
1026process_directive(elif(Cond), Src) :-
1027 !,
1028 current_source_line(Line),
1029 assert_called(Src, '<directive>'(Line), Cond).
1030process_directive(else, _) :- !.
1031process_directive(endif, _) :- !.
1032process_directive(Goal, Src) :-
1033 current_source_line(Line),
1034 process_body(Goal, '<directive>'(Line), Src).
1035
1039
1040process_meta_predicate((A,B), Src) :-
1041 !,
1042 process_meta_predicate(A, Src),
1043 process_meta_predicate(B, Src).
1044process_meta_predicate(Decl, Src) :-
1045 process_meta_head(Src, Decl).
1046
1047process_meta_head(Src, Decl) :- 1048 compound(Decl),
1049 compound_name_arity(Decl, Name, Arity),
1050 compound_name_arity(Head, Name, Arity),
1051 meta_args(1, Arity, Decl, Head, Meta),
1052 ( ( prolog:meta_goal(Head, _)
1053 ; prolog:called_by(Head, _, _, _)
1054 ; prolog:called_by(Head, _)
1055 ; meta_goal(Head, _)
1056 )
1057 -> true
1058 ; assert(meta_goal(Head, Meta, Src))
1059 ).
1060
1061meta_args(I, Arity, _, _, []) :-
1062 I > Arity,
1063 !.
1064meta_args(I, Arity, Decl, Head, [H|T]) :- 1065 arg(I, Decl, 0),
1066 !,
1067 arg(I, Head, H),
1068 I2 is I + 1,
1069 meta_args(I2, Arity, Decl, Head, T).
1070meta_args(I, Arity, Decl, Head, [H|T]) :- 1071 arg(I, Decl, ^),
1072 !,
1073 arg(I, Head, EH),
1074 setof_goal(EH, H),
1075 I2 is I + 1,
1076 meta_args(I2, Arity, Decl, Head, T).
1077meta_args(I, Arity, Decl, Head, [//(H)|T]) :-
1078 arg(I, Decl, //),
1079 !,
1080 arg(I, Head, H),
1081 I2 is I + 1,
1082 meta_args(I2, Arity, Decl, Head, T).
1083meta_args(I, Arity, Decl, Head, [H+A|T]) :- 1084 arg(I, Decl, A),
1085 integer(A), A > 0,
1086 !,
1087 arg(I, Head, H),
1088 I2 is I + 1,
1089 meta_args(I2, Arity, Decl, Head, T).
1090meta_args(I, Arity, Decl, Head, Meta) :-
1091 I2 is I + 1,
1092 meta_args(I2, Arity, Decl, Head, Meta).
1093
1094
1095 1098
1105
1106xref_meta(Source, Head, Called) :-
1107 canonical_source(Source, Src),
1108 xref_meta_src(Head, Called, Src).
1109
1122
1123xref_meta_src(Head, Called, Src) :-
1124 meta_goal(Head, Called, Src),
1125 !.
1126xref_meta_src(Head, Called, _) :-
1127 xref_meta(Head, Called),
1128 !.
1129xref_meta_src(Head, Called, _) :-
1130 compound(Head),
1131 compound_name_arity(Head, Name, Arity),
1132 apply_pred(Name),
1133 Arity > 5,
1134 !,
1135 Extra is Arity - 1,
1136 arg(1, Head, G),
1137 Called = [G+Extra].
1138
1139apply_pred(call). 1140apply_pred(maplist). 1141
1142xref_meta((A, B), [A, B]).
1143xref_meta((A; B), [A, B]).
1144xref_meta((A| B), [A, B]).
1145xref_meta((A -> B), [A, B]).
1146xref_meta((A *-> B), [A, B]).
1147xref_meta(findall(_V,G,_L), [G]).
1148xref_meta(findall(_V,G,_L,_T), [G]).
1149xref_meta(findnsols(_N,_V,G,_L), [G]).
1150xref_meta(findnsols(_N,_V,G,_L,_T), [G]).
1151xref_meta(setof(_V, EG, _L), [G]) :-
1152 setof_goal(EG, G).
1153xref_meta(bagof(_V, EG, _L), [G]) :-
1154 setof_goal(EG, G).
1155xref_meta(forall(A, B), [A, B]).
1156xref_meta(maplist(G,_), [G+1]).
1157xref_meta(maplist(G,_,_), [G+2]).
1158xref_meta(maplist(G,_,_,_), [G+3]).
1159xref_meta(maplist(G,_,_,_,_), [G+4]).
1160xref_meta(map_list_to_pairs(G,_,_), [G+2]).
1161xref_meta(map_assoc(G, _), [G+1]).
1162xref_meta(map_assoc(G, _, _), [G+2]).
1163xref_meta(checklist(G, _L), [G+1]).
1164xref_meta(sublist(G, _, _), [G+1]).
1165xref_meta(include(G, _, _), [G+1]).
1166xref_meta(exclude(G, _, _), [G+1]).
1167xref_meta(partition(G, _, _, _, _), [G+2]).
1168xref_meta(partition(G, _, _, _),[G+1]).
1169xref_meta(call(G), [G]).
1170xref_meta(call(G, _), [G+1]).
1171xref_meta(call(G, _, _), [G+2]).
1172xref_meta(call(G, _, _, _), [G+3]).
1173xref_meta(call(G, _, _, _, _), [G+4]).
1174xref_meta(not(G), [G]).
1175xref_meta(notrace(G), [G]).
1176xref_meta(\+(G), [G]).
1177xref_meta(ignore(G), [G]).
1178xref_meta(once(G), [G]).
1179xref_meta(initialization(G), [G]).
1180xref_meta(initialization(G,_), [G]).
1181xref_meta(retract(Rule), [G]) :- head_of(Rule, G).
1182xref_meta(clause(G, _), [G]).
1183xref_meta(clause(G, _, _), [G]).
1184xref_meta(phrase(G, _A), [//(G)]).
1185xref_meta(phrase(G, _A, _R), [//(G)]).
1186xref_meta(call_dcg(G, _A, _R), [//(G)]).
1187xref_meta(phrase_from_file(G,_),[//(G)]).
1188xref_meta(catch(A, _, B), [A, B]).
1189xref_meta(catch_with_backtrace(A, _, B), [A, B]).
1190xref_meta(thread_create(A,_,_), [A]).
1191xref_meta(thread_create(A,_), [A]).
1192xref_meta(thread_signal(_,A), [A]).
1193xref_meta(thread_at_exit(A), [A]).
1194xref_meta(thread_initialization(A), [A]).
1195xref_meta(engine_create(_,A,_), [A]).
1196xref_meta(engine_create(_,A,_,_), [A]).
1197xref_meta(predsort(A,_,_), [A+3]).
1198xref_meta(call_cleanup(A, B), [A, B]).
1199xref_meta(call_cleanup(A, _, B),[A, B]).
1200xref_meta(setup_call_cleanup(A, B, C),[A, B, C]).
1201xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]).
1202xref_meta(call_residue_vars(A,_), [A]).
1203xref_meta(with_mutex(_,A), [A]).
1204xref_meta(assume(G), [G]). 1205xref_meta(assertion(G), [G]). 1206xref_meta(freeze(_, G), [G]).
1207xref_meta(when(C, A), [C, A]).
1208xref_meta(time(G), [G]). 1209xref_meta(profile(G), [G]).
1210xref_meta(at_halt(G), [G]).
1211xref_meta(call_with_time_limit(_, G), [G]).
1212xref_meta(call_with_depth_limit(G, _, _), [G]).
1213xref_meta(call_with_inference_limit(G, _, _), [G]).
1214xref_meta(alarm(_, G, _), [G]).
1215xref_meta(alarm(_, G, _, _), [G]).
1216xref_meta('$add_directive_wic'(G), [G]).
1217xref_meta(with_output_to(_, G), [G]).
1218xref_meta(if(G), [G]).
1219xref_meta(elif(G), [G]).
1220xref_meta(meta_options(G,_,_), [G+1]).
1221xref_meta(on_signal(_,_,H), [H+1]) :- H \== default.
1222xref_meta(distinct(G), [G]). 1223xref_meta(distinct(_, G), [G]).
1224xref_meta(order_by(_, G), [G]).
1225xref_meta(limit(_, G), [G]).
1226xref_meta(offset(_, G), [G]).
1227xref_meta(reset(G,_,_), [G]).
1228
1229 1230xref_meta(pce_global(_, new(_)), _) :- !, fail.
1231xref_meta(pce_global(_, B), [B+1]).
1232xref_meta(ifmaintainer(G), [G]). 1233xref_meta(listen(_, G), [G]). 1234xref_meta(listen(_, _, G), [G]).
1235xref_meta(in_pce_thread(G), [G]).
1236
1237xref_meta(G, Meta) :- 1238 prolog:meta_goal(G, Meta).
1239xref_meta(G, Meta) :- 1240 meta_goal(G, Meta).
1241
1242setof_goal(EG, G) :-
1243 var(EG), !, G = EG.
1244setof_goal(_^EG, G) :-
1245 !,
1246 setof_goal(EG, G).
1247setof_goal(G, G).
1248
1249
1253
1254head_of(Var, _) :-
1255 var(Var), !, fail.
1256head_of((Head :- _), Head).
1257head_of(Head, Head).
1258
1264
1265xref_hook(Hook) :-
1266 prolog:hook(Hook).
1267xref_hook(Hook) :-
1268 hook(Hook).
1269
1270
1271hook(attr_portray_hook(_,_)).
1272hook(attr_unify_hook(_,_)).
1273hook(attribute_goals(_,_,_)).
1274hook(goal_expansion(_,_)).
1275hook(term_expansion(_,_)).
1276hook(resource(_,_,_)).
1277hook('$pred_option'(_,_,_,_)).
1278
1279hook(emacs_prolog_colours:goal_classification(_,_)).
1280hook(emacs_prolog_colours:term_colours(_,_)).
1281hook(emacs_prolog_colours:goal_colours(_,_)).
1282hook(emacs_prolog_colours:style(_,_)).
1283hook(emacs_prolog_colours:identify(_,_)).
1284hook(pce_principal:pce_class(_,_,_,_,_,_)).
1285hook(pce_principal:send_implementation(_,_,_)).
1286hook(pce_principal:get_implementation(_,_,_,_)).
1287hook(pce_principal:pce_lazy_get_method(_,_,_)).
1288hook(pce_principal:pce_lazy_send_method(_,_,_)).
1289hook(pce_principal:pce_uses_template(_,_)).
1290hook(prolog:locate_clauses(_,_)).
1291hook(prolog:message(_,_,_)).
1292hook(prolog:error_message(_,_,_)).
1293hook(prolog:message_location(_,_,_)).
1294hook(prolog:message_context(_,_,_)).
1295hook(prolog:message_line_element(_,_)).
1296hook(prolog:debug_control_hook(_)).
1297hook(prolog:help_hook(_)).
1298hook(prolog:show_profile_hook(_,_)).
1299hook(prolog:general_exception(_,_)).
1300hook(prolog:predicate_summary(_,_)).
1301hook(prolog:residual_goals(_,_)).
1302hook(prolog_edit:load).
1303hook(prolog_edit:locate(_,_,_)).
1304hook(shlib:unload_all_foreign_libraries).
1305hook(system:'$foreign_registered'(_, _)).
1306hook(predicate_options:option_decl(_,_,_)).
1307hook(user:exception(_,_,_)).
1308hook(user:file_search_path(_,_)).
1309hook(user:library_directory(_)).
1310hook(user:message_hook(_,_,_)).
1311hook(user:portray(_)).
1312hook(user:prolog_clause_name(_,_)).
1313hook(user:prolog_list_goal(_)).
1314hook(user:prolog_predicate_name(_,_)).
1315hook(user:prolog_trace_interception(_,_,_,_)).
1316hook(user:prolog_event_hook(_)).
1317hook(user:prolog_exception_hook(_,_,_,_)).
1318hook(sandbox:safe_primitive(_)).
1319hook(sandbox:safe_meta_predicate(_)).
1320hook(sandbox:safe_meta(_,_)).
1321hook(sandbox:safe_global_variable(_)).
1322hook(sandbox:safe_directive(_)).
1323
1324
1328
1329arith_callable(Var, _) :-
1330 var(Var), !, fail.
1331arith_callable(Module:Spec, Module:Goal) :-
1332 !,
1333 arith_callable(Spec, Goal).
1334arith_callable(Name/Arity, Goal) :-
1335 PredArity is Arity + 1,
1336 functor(Goal, Name, PredArity).
1337
1346
1347process_body(Body, Origin, Src) :-
1348 forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
1349 true).
1350
1355
1356process_goal(Var, _, _, _) :-
1357 var(Var),
1358 !.
1359process_goal(Goal, Origin, Src, P) :-
1360 Goal = (_,_), 1361 !,
1362 phrase(conjunction(Goal), Goals),
1363 process_conjunction(Goals, Origin, Src, P).
1364process_goal(Goal, Origin, Src, _) :- 1365 Goal = (_;_), 1366 !,
1367 phrase(disjunction(Goal), Goals),
1368 forall(member(G, Goals),
1369 process_body(G, Origin, Src)).
1370process_goal(Goal, Origin, Src, P) :-
1371 ( ( xmodule(M, Src)
1372 -> true
1373 ; M = user
1374 ),
1375 ( predicate_property(M:Goal, imported_from(IM))
1376 -> true
1377 ; IM = M
1378 ),
1379 prolog:called_by(Goal, IM, M, Called)
1380 ; prolog:called_by(Goal, Called)
1381 ),
1382 !,
1383 must_be(list, Called),
1384 assert_called(Src, Origin, Goal),
1385 process_called_list(Called, Origin, Src, P).
1386process_goal(Goal, Origin, Src, _) :-
1387 process_xpce_goal(Goal, Origin, Src),
1388 !.
1389process_goal(load_foreign_library(File), _Origin, Src, _) :-
1390 process_foreign(File, Src).
1391process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :-
1392 process_foreign(File, Src).
1393process_goal(use_foreign_library(File), _Origin, Src, _) :-
1394 process_foreign(File, Src).
1395process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :-
1396 process_foreign(File, Src).
1397process_goal(Goal, Origin, Src, P) :-
1398 xref_meta_src(Goal, Metas, Src),
1399 !,
1400 assert_called(Src, Origin, Goal),
1401 process_called_list(Metas, Origin, Src, P).
1402process_goal(Goal, Origin, Src, _) :-
1403 asserting_goal(Goal, Rule),
1404 !,
1405 assert_called(Src, Origin, Goal),
1406 process_assert(Rule, Origin, Src).
1407process_goal(Goal, Origin, Src, P) :-
1408 partial_evaluate(Goal, P),
1409 assert_called(Src, Origin, Goal).
1410
1411disjunction(Var) --> {var(Var), !}, [Var].
1412disjunction((A;B)) --> !, disjunction(A), disjunction(B).
1413disjunction(G) --> [G].
1414
1415conjunction(Var) --> {var(Var), !}, [Var].
1416conjunction((A,B)) --> !, conjunction(A), conjunction(B).
1417conjunction(G) --> [G].
1418
1419shares_vars(RVars, T) :-
1420 term_variables(T, TVars0),
1421 sort(TVars0, TVars),
1422 ord_intersect(RVars, TVars).
1423
1424process_conjunction([], _, _, _).
1425process_conjunction([Disj|Rest], Origin, Src, P) :-
1426 nonvar(Disj),
1427 Disj = (_;_),
1428 Rest \== [],
1429 !,
1430 phrase(disjunction(Disj), Goals),
1431 term_variables(Rest, RVars0),
1432 sort(RVars0, RVars),
1433 partition(shares_vars(RVars), Goals, Sharing, NonSHaring),
1434 forall(member(G, NonSHaring),
1435 process_body(G, Origin, Src)),
1436 ( Sharing == []
1437 -> true
1438 ; maplist(term_variables, Sharing, GVars0),
1439 append(GVars0, GVars1),
1440 sort(GVars1, GVars),
1441 ord_intersection(GVars, RVars, SVars),
1442 VT =.. [v|SVars],
1443 findall(VT,
1444 ( member(G, Sharing),
1445 process_goal(G, Origin, Src, PS),
1446 PS == true
1447 ),
1448 Alts0),
1449 ( Alts0 == []
1450 -> true
1451 ; ( true
1452 ; P = true,
1453 sort(Alts0, Alts1),
1454 variants(Alts1, 10, Alts),
1455 member(VT, Alts)
1456 )
1457 )
1458 ),
1459 process_conjunction(Rest, Origin, Src, P).
1460process_conjunction([H|T], Origin, Src, P) :-
1461 process_goal(H, Origin, Src, P),
1462 process_conjunction(T, Origin, Src, P).
1463
1464
1465process_called_list([], _, _, _).
1466process_called_list([H|T], Origin, Src, P) :-
1467 process_meta(H, Origin, Src, P),
1468 process_called_list(T, Origin, Src, P).
1469
1470process_meta(A+N, Origin, Src, P) :-
1471 !,
1472 ( extend(A, N, AX)
1473 -> process_goal(AX, Origin, Src, P)
1474 ; true
1475 ).
1476process_meta(//(A), Origin, Src, P) :-
1477 !,
1478 process_dcg_goal(A, Origin, Src, P).
1479process_meta(G, Origin, Src, P) :-
1480 process_goal(G, Origin, Src, P).
1481
1486
1487process_dcg_goal(Var, _, _, _) :-
1488 var(Var),
1489 !.
1490process_dcg_goal((A,B), Origin, Src, P) :-
1491 !,
1492 process_dcg_goal(A, Origin, Src, P),
1493 process_dcg_goal(B, Origin, Src, P).
1494process_dcg_goal((A;B), Origin, Src, P) :-
1495 !,
1496 process_dcg_goal(A, Origin, Src, P),
1497 process_dcg_goal(B, Origin, Src, P).
1498process_dcg_goal((A|B), Origin, Src, P) :-
1499 !,
1500 process_dcg_goal(A, Origin, Src, P),
1501 process_dcg_goal(B, Origin, Src, P).
1502process_dcg_goal((A->B), Origin, Src, P) :-
1503 !,
1504 process_dcg_goal(A, Origin, Src, P),
1505 process_dcg_goal(B, Origin, Src, P).
1506process_dcg_goal((A*->B), Origin, Src, P) :-
1507 !,
1508 process_dcg_goal(A, Origin, Src, P),
1509 process_dcg_goal(B, Origin, Src, P).
1510process_dcg_goal({Goal}, Origin, Src, P) :-
1511 !,
1512 process_goal(Goal, Origin, Src, P).
1513process_dcg_goal(List, _Origin, _Src, _) :-
1514 is_list(List),
1515 !. 1516process_dcg_goal(List, _Origin, _Src, _) :-
1517 string(List),
1518 !. 1519process_dcg_goal(Callable, Origin, Src, P) :-
1520 extend(Callable, 2, Goal),
1521 !,
1522 process_goal(Goal, Origin, Src, P).
1523process_dcg_goal(_, _, _, _).
1524
1525
1526extend(Var, _, _) :-
1527 var(Var), !, fail.
1528extend(M:G, N, M:GX) :-
1529 !,
1530 callable(G),
1531 extend(G, N, GX).
1532extend(G, N, GX) :-
1533 ( compound(G)
1534 -> compound_name_arguments(G, Name, Args),
1535 length(Rest, N),
1536 append(Args, Rest, NArgs),
1537 compound_name_arguments(GX, Name, NArgs)
1538 ; atom(G)
1539 -> length(NArgs, N),
1540 compound_name_arguments(GX, G, NArgs)
1541 ).
1542
1543asserting_goal(assert(Rule), Rule).
1544asserting_goal(asserta(Rule), Rule).
1545asserting_goal(assertz(Rule), Rule).
1546asserting_goal(assert(Rule,_), Rule).
1547asserting_goal(asserta(Rule,_), Rule).
1548asserting_goal(assertz(Rule,_), Rule).
1549
1550process_assert(0, _, _) :- !. 1551process_assert((_:-Body), Origin, Src) :-
1552 !,
1553 process_body(Body, Origin, Src).
1554process_assert(_, _, _).
1555
1557
1558variants([], _, []).
1559variants([H|T], Max, List) :-
1560 variants(T, H, Max, List).
1561
1562variants([], H, _, [H]).
1563variants(_, _, 0, []) :- !.
1564variants([H|T], V, Max, List) :-
1565 ( H =@= V
1566 -> variants(T, V, Max, List)
1567 ; List = [V|List2],
1568 Max1 is Max-1,
1569 variants(T, H, Max1, List2)
1570 ).
1571
1583
1584partial_evaluate(Goal, P) :-
1585 eval(Goal),
1586 !,
1587 P = true.
1588partial_evaluate(_, _).
1589
1590eval(X = Y) :-
1591 unify_with_occurs_check(X, Y).
1592
1593
1594 1597
1598pce_goal(new(_,_), new(-, new)).
1599pce_goal(send(_,_), send(arg, msg)).
1600pce_goal(send_class(_,_,_), send_class(arg, arg, msg)).
1601pce_goal(get(_,_,_), get(arg, msg, -)).
1602pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)).
1603pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)).
1604pce_goal(get_object(_,_,_), get_object(arg, msg, -)).
1605
1606process_xpce_goal(G, Origin, Src) :-
1607 pce_goal(G, Process),
1608 !,
1609 assert_called(Src, Origin, G),
1610 ( arg(I, Process, How),
1611 arg(I, G, Term),
1612 process_xpce_arg(How, Term, Origin, Src),
1613 fail
1614 ; true
1615 ).
1616
1617process_xpce_arg(new, Term, Origin, Src) :-
1618 callable(Term),
1619 process_new(Term, Origin, Src).
1620process_xpce_arg(arg, Term, Origin, Src) :-
1621 compound(Term),
1622 process_new(Term, Origin, Src).
1623process_xpce_arg(msg, Term, Origin, Src) :-
1624 compound(Term),
1625 ( arg(_, Term, Arg),
1626 process_xpce_arg(arg, Arg, Origin, Src),
1627 fail
1628 ; true
1629 ).
1630
1631process_new(_M:_Term, _, _) :- !. 1632process_new(Term, Origin, Src) :-
1633 assert_new(Src, Origin, Term),
1634 ( compound(Term),
1635 arg(_, Term, Arg),
1636 process_xpce_arg(arg, Arg, Origin, Src),
1637 fail
1638 ; true
1639 ).
1640
1641assert_new(_, _, Term) :-
1642 \+ callable(Term),
1643 !.
1644assert_new(Src, Origin, Control) :-
1645 functor_name(Control, Class),
1646 pce_control_class(Class),
1647 !,
1648 forall(arg(_, Control, Arg),
1649 assert_new(Src, Origin, Arg)).
1650assert_new(Src, Origin, Term) :-
1651 compound(Term),
1652 arg(1, Term, Prolog),
1653 Prolog == @(prolog),
1654 ( Term =.. [message, _, Selector | T],
1655 atom(Selector)
1656 -> Called =.. [Selector|T],
1657 process_body(Called, Origin, Src)
1658 ; Term =.. [?, _, Selector | T],
1659 atom(Selector)
1660 -> append(T, [_R], T2),
1661 Called =.. [Selector|T2],
1662 process_body(Called, Origin, Src)
1663 ),
1664 fail.
1665assert_new(_, _, @(_)) :- !.
1666assert_new(Src, _, Term) :-
1667 functor_name(Term, Name),
1668 assert_used_class(Src, Name).
1669
1670
1671pce_control_class(and).
1672pce_control_class(or).
1673pce_control_class(if).
1674pce_control_class(not).
1675
1676
1677 1680
1682
1683process_use_module(_Module:_Files, _, _) :- !. 1684process_use_module([], _, _) :- !.
1685process_use_module([H|T], Src, Reexport) :-
1686 !,
1687 process_use_module(H, Src, Reexport),
1688 process_use_module(T, Src, Reexport).
1689process_use_module(library(pce), Src, Reexport) :- 1690 !,
1691 xref_public_list(library(pce), Path, Exports, Src),
1692 forall(member(Import, Exports),
1693 process_pce_import(Import, Src, Path, Reexport)).
1694process_use_module(File, Src, Reexport) :-
1695 ( xoption(Src, silent(Silent))
1696 -> Extra = [silent(Silent)]
1697 ; Extra = [silent(true)]
1698 ),
1699 ( xref_public_list(File, Src,
1700 [ path(Path),
1701 module(M),
1702 exports(Exports),
1703 public(Public),
1704 meta(Meta)
1705 | Extra
1706 ])
1707 -> assert(uses_file(File, Src, Path)),
1708 assert_import(Src, Exports, _, Path, Reexport),
1709 assert_xmodule_callable(Exports, M, Src, Path),
1710 assert_xmodule_callable(Public, M, Src, Path),
1711 maplist(process_meta_head(Src), Meta),
1712 ( File = library(chr) 1713 -> assert(mode(chr, Src))
1714 ; true
1715 )
1716 ; assert(uses_file(File, Src, '<not_found>'))
1717 ).
1718
1719process_pce_import(Name/Arity, Src, Path, Reexport) :-
1720 atom(Name),
1721 integer(Arity),
1722 !,
1723 functor(Term, Name, Arity),
1724 ( \+ system_predicate(Term),
1725 \+ Term = pce_error(_) 1726 -> assert_import(Src, [Name/Arity], _, Path, Reexport)
1727 ; true
1728 ).
1729process_pce_import(op(P,T,N), Src, _, _) :-
1730 xref_push_op(Src, P, T, N).
1731
1735
1736process_use_module2(File, Import, Src, Reexport) :-
1737 ( xref_source_file(File, Path, Src)
1738 -> assert(uses_file(File, Src, Path)),
1739 ( catch(public_list(Path, _, Meta, Export, _Public, []), _, fail)
1740 -> assert_import(Src, Import, Export, Path, Reexport),
1741 forall(( member(Head, Meta),
1742 imported(Head, _, Path)
1743 ),
1744 process_meta_head(Src, Head))
1745 ; true
1746 )
1747 ; assert(uses_file(File, Src, '<not_found>'))
1748 ).
1749
1750
1778
1779xref_public_list(File, Src, Options) :-
1780 option(path(Path), Options, _),
1781 option(module(Module), Options, _),
1782 option(exports(Exports), Options, _),
1783 option(public(Public), Options, _),
1784 option(meta(Meta), Options, _),
1785 xref_source_file(File, Path, Src, Options),
1786 public_list(Path, Module, Meta, Exports, Public, Options).
1787
1807
1808xref_public_list(File, Path, Export, Src) :-
1809 xref_source_file(File, Path, Src),
1810 public_list(Path, _, _, Export, _, []).
1811xref_public_list(File, Path, Module, Export, Meta, Src) :-
1812 xref_source_file(File, Path, Src),
1813 public_list(Path, Module, Meta, Export, _, []).
1814xref_public_list(File, Path, Module, Export, Public, Meta, Src) :-
1815 xref_source_file(File, Path, Src),
1816 public_list(Path, Module, Meta, Export, Public, []).
1817
1825
1826:- dynamic public_list_cache/6. 1827:- volatile public_list_cache/6. 1828
1829public_list(Path, Module, Meta, Export, Public, _Options) :-
1830 public_list_cache(Path, Modified,
1831 Module0, Meta0, Export0, Public0),
1832 time_file(Path, ModifiedNow),
1833 ( abs(Modified-ModifiedNow) < 0.0001
1834 -> !,
1835 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0)
1836 ; retractall(public_list_cache(Path, _, _, _, _, _)),
1837 fail
1838 ).
1839public_list(Path, Module, Meta, Export, Public, Options) :-
1840 public_list_nc(Path, Module0, Meta0, Export0, Public0, Options),
1841 ( Error = error(_,_),
1842 catch(time_file(Path, Modified), Error, fail)
1843 -> asserta(public_list_cache(Path, Modified,
1844 Module0, Meta0, Export0, Public0))
1845 ; true
1846 ),
1847 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0).
1848
1849public_list_nc(Path, Module, Meta, Export, Public, Options) :-
1850 in_temporary_module(
1851 TempModule,
1852 true,
1853 public_list_diff(TempModule, Path, Module,
1854 Meta, [], Export, [], Public, [], Options)).
1855
1856
1857public_list_diff(TempModule,
1858 Path, Module, Meta, MT, Export, Rest, Public, PT, Options) :-
1859 setup_call_cleanup(
1860 public_list_setup(TempModule, Path, In, State),
1861 phrase(read_directives(In, Options, [true]), Directives),
1862 public_list_cleanup(In, State)),
1863 public_list(Directives, Path, Module, Meta, MT, Export, Rest, Public, PT).
1864
1865public_list_setup(TempModule, Path, In, state(OldM, OldXref)) :-
1866 prolog_open_source(Path, In),
1867 '$set_source_module'(OldM, TempModule),
1868 set_xref(OldXref).
1869
1870public_list_cleanup(In, state(OldM, OldXref)) :-
1871 '$set_source_module'(OldM),
1872 set_prolog_flag(xref, OldXref),
1873 prolog_close_source(In).
1874
1875
1876read_directives(In, Options, State) -->
1877 { repeat,
1878 catch(prolog_read_source_term(In, Term, Expanded,
1879 [ process_comment(true),
1880 syntax_errors(error)
1881 ]),
1882 E, report_syntax_error(E, -, Options))
1883 -> nonvar(Term),
1884 Term = (:-_)
1885 },
1886 !,
1887 terms(Expanded, State, State1),
1888 read_directives(In, Options, State1).
1889read_directives(_, _, _) --> [].
1890
1891terms(Var, State, State) --> { var(Var) }, !.
1892terms([H|T], State0, State) -->
1893 !,
1894 terms(H, State0, State1),
1895 terms(T, State1, State).
1896terms((:-if(Cond)), State0, [True|State0]) -->
1897 !,
1898 { eval_cond(Cond, True) }.
1899terms((:-elif(Cond)), [True0|State], [True|State]) -->
1900 !,
1901 { eval_cond(Cond, True1),
1902 elif(True0, True1, True)
1903 }.
1904terms((:-else), [True0|State], [True|State]) -->
1905 !,
1906 { negate(True0, True) }.
1907terms((:-endif), [_|State], State) --> !.
1908terms(H, State, State) -->
1909 ( {State = [true|_]}
1910 -> [H]
1911 ; []
1912 ).
1913
1914eval_cond(Cond, true) :-
1915 catch(Cond, _, fail),
1916 !.
1917eval_cond(_, false).
1918
1919elif(true, _, else_false) :- !.
1920elif(false, true, true) :- !.
1921elif(True, _, True).
1922
1923negate(true, false).
1924negate(false, true).
1925negate(else_false, else_false).
1926
1927public_list([(:- module(Module, Export0))|Decls], Path,
1928 Module, Meta, MT, Export, Rest, Public, PT) :-
1929 !,
1930 append(Export0, Reexport, Export),
1931 public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT).
1932public_list([(:- encoding(_))|Decls], Path,
1933 Module, Meta, MT, Export, Rest, Public, PT) :-
1934 public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT).
1935
1936public_list_([], _, Meta, Meta, Export, Export, Public, Public).
1937public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :-
1938 public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0),
1939 !,
1940 public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT).
1941public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :-
1942 public_list_(T, Path, Meta, MT, Export, Rest, Public, PT).
1943
1944public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :-
1945 reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT).
1946public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :-
1947 public_from_import(Import, Spec, Path, Reexport, Rest).
1948public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :-
1949 phrase(meta_decls(Decl), Meta, MT).
1950public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :-
1951 phrase(public_decls(Decl), Public, PT).
1952
1956
1957reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !.
1958reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :-
1959 !,
1960 xref_source_file(H, Path, Src),
1961 public_list(Path, _Module, Meta0, Export0, Public0, []),
1962 append(Meta0, MT1, Meta),
1963 append(Export0, ET1, Export),
1964 append(Public0, PT1, Public),
1965 reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT).
1966reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :-
1967 xref_source_file(Spec, Path, Src),
1968 public_list(Path, _Module, Meta0, Export0, Public0, []),
1969 append(Meta0, MT, Meta),
1970 append(Export0, ET, Export),
1971 append(Public0, PT, Public).
1972
1973public_from_import(except(Map), Path, Src, Export, Rest) :-
1974 !,
1975 xref_public_list(Path, _, AllExports, Src),
1976 except(Map, AllExports, NewExports),
1977 append(NewExports, Rest, Export).
1978public_from_import(Import, _, _, Export, Rest) :-
1979 import_name_map(Import, Export, Rest).
1980
1981
1983
1984except([], Exports, Exports).
1985except([PI0 as NewName|Map], Exports0, Exports) :-
1986 !,
1987 canonical_pi(PI0, PI),
1988 map_as(Exports0, PI, NewName, Exports1),
1989 except(Map, Exports1, Exports).
1990except([PI0|Map], Exports0, Exports) :-
1991 canonical_pi(PI0, PI),
1992 select(PI2, Exports0, Exports1),
1993 same_pi(PI, PI2),
1994 !,
1995 except(Map, Exports1, Exports).
1996
1997
1998map_as([PI|T], Repl, As, [PI2|T]) :-
1999 same_pi(Repl, PI),
2000 !,
2001 pi_as(PI, As, PI2).
2002map_as([H|T0], Repl, As, [H|T]) :-
2003 map_as(T0, Repl, As, T).
2004
2005pi_as(_/Arity, Name, Name/Arity).
2006pi_as(_//Arity, Name, Name//Arity).
2007
2008import_name_map([], L, L).
2009import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :-
2010 !,
2011 import_name_map(T0, T, Tail).
2012import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :-
2013 !,
2014 import_name_map(T0, T, Tail).
2015import_name_map([H|T0], [H|T], Tail) :-
2016 import_name_map(T0, T, Tail).
2017
2018canonical_pi(Name//Arity0, PI) :-
2019 integer(Arity0),
2020 !,
2021 PI = Name/Arity,
2022 Arity is Arity0 + 2.
2023canonical_pi(PI, PI).
2024
2025same_pi(Canonical, PI2) :-
2026 canonical_pi(PI2, Canonical).
2027
2028meta_decls(Var) -->
2029 { var(Var) },
2030 !.
2031meta_decls((A,B)) -->
2032 !,
2033 meta_decls(A),
2034 meta_decls(B).
2035meta_decls(A) -->
2036 [A].
2037
2038public_decls(Var) -->
2039 { var(Var) },
2040 !.
2041public_decls((A,B)) -->
2042 !,
2043 public_decls(A),
2044 public_decls(B).
2045public_decls(A) -->
2046 [A].
2047
2048 2051
2052process_include([], _) :- !.
2053process_include([H|T], Src) :-
2054 !,
2055 process_include(H, Src),
2056 process_include(T, Src).
2057process_include(File, Src) :-
2058 callable(File),
2059 !,
2060 ( once(xref_input(ParentSrc, _)),
2061 xref_source_file(File, Path, ParentSrc)
2062 -> ( ( uses_file(_, Src, Path)
2063 ; Path == Src
2064 )
2065 -> true
2066 ; assert(uses_file(File, Src, Path)),
2067 ( xoption(Src, process_include(true))
2068 -> findall(O, xoption(Src, O), Options),
2069 setup_call_cleanup(
2070 open_include_file(Path, In, Refs),
2071 collect(Src, Path, In, Options),
2072 close_include(In, Refs))
2073 ; true
2074 )
2075 )
2076 ; assert(uses_file(File, Src, '<not_found>'))
2077 ).
2078process_include(_, _).
2079
2085
2086open_include_file(Path, In, [Ref]) :-
2087 once(xref_input(_, Parent)),
2088 stream_property(Parent, encoding(Enc)),
2089 '$push_input_context'(xref_include),
2090 catch(( prolog:xref_open_source(Path, In)
2091 -> set_stream(In, encoding(Enc))
2092 ; include_encoding(Enc, Options),
2093 open(Path, read, In, Options)
2094 ), E,
2095 ( '$pop_input_context', throw(E))),
2096 catch(( peek_char(In, #) 2097 -> skip(In, 10)
2098 ; true
2099 ), E,
2100 ( close_include(In, []), throw(E))),
2101 asserta(xref_input(Path, In), Ref).
2102
2103include_encoding(wchar_t, []) :- !.
2104include_encoding(Enc, [encoding(Enc)]).
2105
2106
2107close_include(In, Refs) :-
2108 maplist(erase, Refs),
2109 close(In, [force(true)]),
2110 '$pop_input_context'.
2111
2115
2116process_foreign(Spec, Src) :-
2117 ground(Spec),
2118 current_foreign_library(Spec, Defined),
2119 !,
2120 ( xmodule(Module, Src)
2121 -> true
2122 ; Module = user
2123 ),
2124 process_foreign_defined(Defined, Module, Src).
2125process_foreign(_, _).
2126
2127process_foreign_defined([], _, _).
2128process_foreign_defined([H|T], M, Src) :-
2129 ( H = M:Head
2130 -> assert_foreign(Src, Head)
2131 ; assert_foreign(Src, H)
2132 ),
2133 process_foreign_defined(T, M, Src).
2134
2135
2136 2139
2149
2150process_chr(@(_Name, Rule), Src) :-
2151 mode(chr, Src),
2152 process_chr(Rule, Src).
2153process_chr(pragma(Rule, _Pragma), Src) :-
2154 mode(chr, Src),
2155 process_chr(Rule, Src).
2156process_chr(<=>(Head, Body), Src) :-
2157 mode(chr, Src),
2158 chr_head(Head, Src, H),
2159 chr_body(Body, H, Src).
2160process_chr(==>(Head, Body), Src) :-
2161 mode(chr, Src),
2162 chr_head(Head, H, Src),
2163 chr_body(Body, H, Src).
2164process_chr((:- chr_constraint(_)), Src) :-
2165 ( mode(chr, Src)
2166 -> true
2167 ; assert(mode(chr, Src))
2168 ).
2169
2170chr_head(X, _, _) :-
2171 var(X),
2172 !. 2173chr_head(\(A,B), Src, H) :-
2174 chr_head(A, Src, H),
2175 process_body(B, H, Src).
2176chr_head((H0,B), Src, H) :-
2177 chr_defined(H0, Src, H),
2178 process_body(B, H, Src).
2179chr_head(H0, Src, H) :-
2180 chr_defined(H0, Src, H).
2181
2182chr_defined(X, _, _) :-
2183 var(X),
2184 !.
2185chr_defined(#(C,_Id), Src, C) :-
2186 !,
2187 assert_constraint(Src, C).
2188chr_defined(A, Src, A) :-
2189 assert_constraint(Src, A).
2190
2191chr_body(X, From, Src) :-
2192 var(X),
2193 !,
2194 process_body(X, From, Src).
2195chr_body('|'(Guard, Goals), H, Src) :-
2196 !,
2197 chr_body(Guard, H, Src),
2198 chr_body(Goals, H, Src).
2199chr_body(G, From, Src) :-
2200 process_body(G, From, Src).
2201
2202assert_constraint(_, Head) :-
2203 var(Head),
2204 !.
2205assert_constraint(Src, Head) :-
2206 constraint(Head, Src, _),
2207 !.
2208assert_constraint(Src, Head) :-
2209 generalise_term(Head, Term),
2210 current_source_line(Line),
2211 assert(constraint(Term, Src, Line)).
2212
2213
2214 2217
2222
2223assert_called(_, _, Var) :-
2224 var(Var),
2225 !.
2226assert_called(Src, From, Goal) :-
2227 var(From),
2228 !,
2229 assert_called(Src, '<unknown>', Goal).
2230assert_called(_, _, Goal) :-
2231 expand_hide_called(Goal),
2232 !.
2233assert_called(Src, Origin, M:G) :-
2234 !,
2235 ( atom(M),
2236 callable(G)
2237 -> current_condition(Cond),
2238 ( xmodule(M, Src) 2239 -> assert_called(Src, Origin, G)
2240 ; called(M:G, Src, Origin, Cond) 2241 -> true
2242 ; hide_called(M:G, Src) 2243 -> true
2244 ; generalise(Origin, OTerm),
2245 generalise(G, GTerm)
2246 -> assert(called(M:GTerm, Src, OTerm, Cond))
2247 ; true
2248 )
2249 ; true 2250 ).
2251assert_called(Src, _, Goal) :-
2252 ( xmodule(M, Src)
2253 -> M \== system
2254 ; M = user
2255 ),
2256 hide_called(M:Goal, Src),
2257 !.
2258assert_called(Src, Origin, Goal) :-
2259 current_condition(Cond),
2260 ( called(Goal, Src, Origin, Cond)
2261 -> true
2262 ; generalise(Origin, OTerm),
2263 generalise(Goal, Term)
2264 -> assert(called(Term, Src, OTerm, Cond))
2265 ; true
2266 ).
2267
2268
2273
2274expand_hide_called(pce_principal:send_implementation(_, _, _)).
2275expand_hide_called(pce_principal:get_implementation(_, _, _, _)).
2276expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)).
2277expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)).
2278
2279assert_defined(Src, Goal) :-
2280 defined(Goal, Src, _),
2281 !.
2282assert_defined(Src, Goal) :-
2283 generalise(Goal, Term),
2284 current_source_line(Line),
2285 assert(defined(Term, Src, Line)).
2286
2287assert_foreign(Src, Goal) :-
2288 foreign(Goal, Src, _),
2289 !.
2290assert_foreign(Src, Goal) :-
2291 generalise(Goal, Term),
2292 current_source_line(Line),
2293 assert(foreign(Term, Src, Line)).
2294
2304
2305assert_import(_, [], _, _, _) :- !.
2306assert_import(Src, [H|T], Export, From, Reexport) :-
2307 !,
2308 assert_import(Src, H, Export, From, Reexport),
2309 assert_import(Src, T, Export, From, Reexport).
2310assert_import(Src, except(Except), Export, From, Reexport) :-
2311 !,
2312 is_list(Export),
2313 !,
2314 except(Except, Export, Import),
2315 assert_import(Src, Import, _All, From, Reexport).
2316assert_import(Src, Import as Name, Export, From, Reexport) :-
2317 !,
2318 pi_to_head(Import, Term0),
2319 rename_goal(Term0, Name, Term),
2320 ( in_export_list(Term0, Export)
2321 -> assert(imported(Term, Src, From)),
2322 assert_reexport(Reexport, Src, Term)
2323 ; current_source_line(Line),
2324 assert_called(Src, '<directive>'(Line), Term0)
2325 ).
2326assert_import(Src, Import, Export, From, Reexport) :-
2327 pi_to_head(Import, Term),
2328 !,
2329 ( in_export_list(Term, Export)
2330 -> assert(imported(Term, Src, From)),
2331 assert_reexport(Reexport, Src, Term)
2332 ; current_source_line(Line),
2333 assert_called(Src, '<directive>'(Line), Term)
2334 ).
2335assert_import(Src, op(P,T,N), _, _, _) :-
2336 xref_push_op(Src, P,T,N).
2337
2338in_export_list(_Head, Export) :-
2339 var(Export),
2340 !.
2341in_export_list(Head, Export) :-
2342 member(PI, Export),
2343 pi_to_head(PI, Head).
2344
2345assert_reexport(false, _, _) :- !.
2346assert_reexport(true, Src, Term) :-
2347 assert(exported(Term, Src)).
2348
2352
2353process_import(M:PI, Src) :-
2354 pi_to_head(PI, Head),
2355 !,
2356 ( atom(M),
2357 current_module(M),
2358 module_property(M, file(From))
2359 -> true
2360 ; From = '<unknown>'
2361 ),
2362 assert(imported(Head, Src, From)).
2363process_import(_, _).
2364
2371
2372assert_xmodule_callable([], _, _, _).
2373assert_xmodule_callable([PI|T], M, Src, From) :-
2374 ( pi_to_head(M:PI, Head)
2375 -> assert(imported(Head, Src, From))
2376 ; true
2377 ),
2378 assert_xmodule_callable(T, M, Src, From).
2379
2380
2384
2385assert_op(Src, op(P,T,M:N)) :-
2386 ( '$current_source_module'(M)
2387 -> Name = N
2388 ; Name = M:N
2389 ),
2390 ( xop(Src, op(P,T,Name))
2391 -> true
2392 ; assert(xop(Src, op(P,T,Name)))
2393 ).
2394
2399
2400assert_module(Src, Module) :-
2401 xmodule(Module, Src),
2402 !.
2403assert_module(Src, Module) :-
2404 '$set_source_module'(Module),
2405 assert(xmodule(Module, Src)),
2406 ( module_property(Module, class(system))
2407 -> retractall(xoption(Src, register_called(_))),
2408 assert(xoption(Src, register_called(all)))
2409 ; true
2410 ).
2411
2412assert_module_export(_, []) :- !.
2413assert_module_export(Src, [H|T]) :-
2414 !,
2415 assert_module_export(Src, H),
2416 assert_module_export(Src, T).
2417assert_module_export(Src, PI) :-
2418 pi_to_head(PI, Term),
2419 !,
2420 assert(exported(Term, Src)).
2421assert_module_export(Src, op(P, A, N)) :-
2422 xref_push_op(Src, P, A, N).
2423
2427
2428assert_module3([], _) :- !.
2429assert_module3([H|T], Src) :-
2430 !,
2431 assert_module3(H, Src),
2432 assert_module3(T, Src).
2433assert_module3(Option, Src) :-
2434 process_use_module(library(dialect/Option), Src, false).
2435
2436
2442
2443process_predicates(Closure, Preds, Src) :-
2444 is_list(Preds),
2445 !,
2446 process_predicate_list(Preds, Closure, Src).
2447process_predicates(Closure, Preds, Src) :-
2448 process_predicate_comma(Preds, Closure, Src).
2449
2450process_predicate_list([], _, _).
2451process_predicate_list([H|T], Closure, Src) :-
2452 ( nonvar(H)
2453 -> call(Closure, H, Src)
2454 ; true
2455 ),
2456 process_predicate_list(T, Closure, Src).
2457
2458process_predicate_comma(Var, _, _) :-
2459 var(Var),
2460 !.
2461process_predicate_comma(M:(A,B), Closure, Src) :-
2462 !,
2463 process_predicate_comma(M:A, Closure, Src),
2464 process_predicate_comma(M:B, Closure, Src).
2465process_predicate_comma((A,B), Closure, Src) :-
2466 !,
2467 process_predicate_comma(A, Closure, Src),
2468 process_predicate_comma(B, Closure, Src).
2469process_predicate_comma(A, Closure, Src) :-
2470 call(Closure, A, Src).
2471
2472
2473assert_dynamic(PI, Src) :-
2474 pi_to_head(PI, Term),
2475 ( thread_local(Term, Src, _) 2476 -> true 2477 ; current_source_line(Line),
2478 assert(dynamic(Term, Src, Line))
2479 ).
2480
2481assert_thread_local(PI, Src) :-
2482 pi_to_head(PI, Term),
2483 current_source_line(Line),
2484 assert(thread_local(Term, Src, Line)).
2485
2486assert_multifile(PI, Src) :- 2487 pi_to_head(PI, Term),
2488 current_source_line(Line),
2489 assert(multifile(Term, Src, Line)).
2490
2491assert_public(PI, Src) :- 2492 pi_to_head(PI, Term),
2493 current_source_line(Line),
2494 assert_called(Src, '<public>'(Line), Term),
2495 assert(public(Term, Src, Line)).
2496
2497assert_export(PI, Src) :- 2498 pi_to_head(PI, Term),
2499 !,
2500 assert(exported(Term, Src)).
2501
2506
2507pi_to_head(Var, _) :-
2508 var(Var), !, fail.
2509pi_to_head(M:PI, M:Term) :-
2510 !,
2511 pi_to_head(PI, Term).
2512pi_to_head(Name/Arity, Term) :-
2513 functor(Term, Name, Arity).
2514pi_to_head(Name//DCGArity, Term) :-
2515 Arity is DCGArity+2,
2516 functor(Term, Name, Arity).
2517
2518
2519assert_used_class(Src, Name) :-
2520 used_class(Name, Src),
2521 !.
2522assert_used_class(Src, Name) :-
2523 assert(used_class(Name, Src)).
2524
2525assert_defined_class(Src, Name, _Meta, _Super, _) :-
2526 defined_class(Name, _, _, Src, _),
2527 !.
2528assert_defined_class(_, _, _, -, _) :- !. 2529assert_defined_class(Src, Name, Meta, Super, Summary) :-
2530 current_source_line(Line),
2531 ( Summary == @(default)
2532 -> Atom = ''
2533 ; is_list(Summary)
2534 -> atom_codes(Atom, Summary)
2535 ; string(Summary)
2536 -> atom_concat(Summary, '', Atom)
2537 ),
2538 assert(defined_class(Name, Super, Atom, Src, Line)),
2539 ( Meta = @(_)
2540 -> true
2541 ; assert_used_class(Src, Meta)
2542 ),
2543 assert_used_class(Src, Super).
2544
2545assert_defined_class(Src, Name, imported_from(_File)) :-
2546 defined_class(Name, _, _, Src, _),
2547 !.
2548assert_defined_class(Src, Name, imported_from(File)) :-
2549 assert(defined_class(Name, _, '', Src, file(File))).
2550
2551
2552 2555
2559
2560generalise(Var, Var) :-
2561 var(Var),
2562 !. 2563generalise(pce_principal:send_implementation(Id, _, _),
2564 pce_principal:send_implementation(Id, _, _)) :-
2565 atom(Id),
2566 !.
2567generalise(pce_principal:get_implementation(Id, _, _, _),
2568 pce_principal:get_implementation(Id, _, _, _)) :-
2569 atom(Id),
2570 !.
2571generalise('<directive>'(Line), '<directive>'(Line)) :- !.
2572generalise(Module:Goal0, Module:Goal) :-
2573 atom(Module),
2574 !,
2575 generalise(Goal0, Goal).
2576generalise(Term0, Term) :-
2577 callable(Term0),
2578 generalise_term(Term0, Term).
2579
2580
2581 2584
2592
2593:- multifile
2594 prolog:xref_source_directory/2, 2595 prolog:xref_source_file/3. 2596
2597
2602
2603xref_source_file(Plain, File, Source) :-
2604 xref_source_file(Plain, File, Source, []).
2605
2606xref_source_file(QSpec, File, Source, Options) :-
2607 nonvar(QSpec), QSpec = _:Spec,
2608 !,
2609 must_be(acyclic, Spec),
2610 xref_source_file(Spec, File, Source, Options).
2611xref_source_file(Spec, File, Source, Options) :-
2612 nonvar(Spec),
2613 prolog:xref_source_file(Spec, File,
2614 [ relative_to(Source)
2615 | Options
2616 ]),
2617 !.
2618xref_source_file(Plain, File, Source, Options) :-
2619 atom(Plain),
2620 \+ is_absolute_file_name(Plain),
2621 ( prolog:xref_source_directory(Source, Dir)
2622 -> true
2623 ; atom(Source),
2624 file_directory_name(Source, Dir)
2625 ),
2626 atomic_list_concat([Dir, /, Plain], Spec0),
2627 absolute_file_name(Spec0, Spec),
2628 do_xref_source_file(Spec, File, Options),
2629 !.
2630xref_source_file(Spec, File, Source, Options) :-
2631 do_xref_source_file(Spec, File,
2632 [ relative_to(Source)
2633 | Options
2634 ]),
2635 !.
2636xref_source_file(_, _, _, Options) :-
2637 option(silent(true), Options),
2638 !,
2639 fail.
2640xref_source_file(Spec, _, Src, _Options) :-
2641 verbose(Src),
2642 print_message(warning, error(existence_error(file, Spec), _)),
2643 fail.
2644
2645do_xref_source_file(Spec, File, Options) :-
2646 nonvar(Spec),
2647 option(file_type(Type), Options, prolog),
2648 absolute_file_name(Spec, File,
2649 [ file_type(Type),
2650 access(read),
2651 file_errors(fail)
2652 ]),
2653 !.
2654
2658
2659canonical_source(Source, Src) :-
2660 ( ground(Source)
2661 -> prolog_canonical_source(Source, Src)
2662 ; Source = Src
2663 ).
2664
2669
2670goal_name_arity(Goal, Name, Arity) :-
2671 ( compound(Goal)
2672 -> compound_name_arity(Goal, Name, Arity)
2673 ; atom(Goal)
2674 -> Name = Goal, Arity = 0
2675 ).
2676
2677generalise_term(Specific, General) :-
2678 ( compound(Specific)
2679 -> compound_name_arity(Specific, Name, Arity),
2680 compound_name_arity(General, Name, Arity)
2681 ; General = Specific
2682 ).
2683
2684functor_name(Term, Name) :-
2685 ( compound(Term)
2686 -> compound_name_arity(Term, Name, _)
2687 ; atom(Term)
2688 -> Name = Term
2689 ).
2690
2691rename_goal(Goal0, Name, Goal) :-
2692 ( compound(Goal0)
2693 -> compound_name_arity(Goal0, _, Arity),
2694 compound_name_arity(Goal, Name, Arity)
2695 ; Goal = Name
2696 )