37
38:- module(prolog_xref,
39 [ xref_source/1, 40 xref_source/2, 41 xref_called/3, 42 xref_called/4, 43 xref_called/5, 44 xref_defined/3, 45 xref_definition_line/2, 46 xref_exported/2, 47 xref_module/2, 48 xref_uses_file/3, 49 xref_op/2, 50 xref_prolog_flag/4, 51 xref_comment/3, 52 xref_comment/4, 53 xref_object_comment/4, 54 xref_object_signature/3, 55 xref_mode/3, 56 xref_option/2, 57 xref_clean/1, 58 xref_current_source/1, 59 xref_done/2, 60 xref_built_in/1, 61 xref_source_file/3, 62 xref_source_file/4, 63 xref_public_list/3, 64 xref_public_list/4, 65 xref_public_list/6, 66 xref_public_list/7, 67 xref_meta/3, 68 xref_meta/2, 69 xref_hook/1, 70 71 xref_used_class/2, 72 xref_defined_class/3 73 ]). 74:- autoload(library(apply),[maplist/2,partition/4,maplist/3]). 75:- use_module(library(debug),[debug/3]). 76:- autoload(library(dialect),[expects_dialect/1]). 77:- autoload(library(error),[must_be/2,instantiation_error/1]). 78:- autoload(library(lists),[member/2,append/2,append/3,select/3]). 79:- autoload(library(operators),[push_op/3]). 80:- autoload(library(option),[option/2,option/3]). 81:- autoload(library(ordsets),[ord_intersect/2,ord_intersection/3]). 82:- autoload(library(prolog_code), [pi_head/2]). 83:- autoload(library(prolog_source),
84 [ prolog_canonical_source/2,
85 prolog_open_source/2,
86 prolog_close_source/1,
87 prolog_read_source_term/4,
88 prolog_file_directives/3
89 ]). 90
91:- if(exists_source(library(shlib))). 92:- autoload(library(shlib),[current_foreign_library/2]). 93:- endif. 94:- autoload(library(solution_sequences),[distinct/2,limit/2]). 95
96:- if(exists_source(library(pldoc))). 97:- use_module(library(pldoc), []). 98:- use_module(library(pldoc/doc_process)). 99
100:- endif. 101
102:- predicate_options(xref_source/2, 2,
103 [ silent(boolean),
104 module(atom),
105 register_called(oneof([all,non_iso,non_built_in])),
106 comments(oneof([store,collect,ignore])),
107 process_include(boolean),
108 stream(stream)
109 ]). 110
111
112:- dynamic
113 called/5, 114 (dynamic)/3, 115 (thread_local)/3, 116 (multifile)/3, 117 (public)/3, 118 (declared)/4, 119 defined/3, 120 meta_goal/3, 121 foreign/3, 122 constraint/3, 123 imported/3, 124 exported/2, 125 xmodule/2, 126 uses_file/3, 127 xop/2, 128 source/2, 129 used_class/2, 130 defined_class/5, 131 (mode)/2, 132 xoption/2, 133 xflag/4, 134 grammar_rule/2, 135 module_comment/3, 136 pred_comment/4, 137 pred_comment_link/3, 138 pred_mode/3, 139 object_comment/4, 140 object_signature/3. 141
142:- create_prolog_flag(xref, false, [type(boolean)]). 143
178
179:- predicate_options(xref_source_file/4, 4,
180 [ file_type(oneof([txt,prolog,directory])),
181 silent(boolean)
182 ]). 183:- predicate_options(xref_public_list/3, 3,
184 [ path(-atom),
185 module(-atom),
186 exports(-list(any)),
187 public(-list(any)),
188 meta(-list(any)),
189 silent(boolean)
190 ]). 191
192
193 196
203
211
216
221
222:- multifile
223 prolog:called_by/4, 224 prolog:called_by/2, 225 prolog:meta_goal/2, 226 prolog:hook/1, 227 prolog:generated_predicate/1, 228 prolog:no_autoload_module/1, 229 prolog:xref_source_time/2. 230
231:- meta_predicate
232 prolog:generated_predicate(:). 233
234:- meta_predicate
235 process_predicates(2, +, +). 236
237 240
246
247hide_called(Callable, Src) :-
248 xoption(Src, register_called(Which)),
249 !,
250 mode_hide_called(Which, Callable).
251hide_called(Callable, _) :-
252 mode_hide_called(non_built_in, Callable).
253
254mode_hide_called(all, _) :- !, fail.
255mode_hide_called(non_iso, _:Goal) :-
256 goal_name_arity(Goal, Name, Arity),
257 current_predicate(system:Name/Arity),
258 predicate_property(system:Goal, iso).
259mode_hide_called(non_built_in, _:Goal) :-
260 goal_name_arity(Goal, Name, Arity),
261 current_predicate(system:Name/Arity),
262 predicate_property(system:Goal, built_in).
263mode_hide_called(non_built_in, M:Goal) :-
264 goal_name_arity(Goal, Name, Arity),
265 current_predicate(M:Name/Arity),
266 predicate_property(M:Goal, built_in).
267
271
272system_predicate(Goal) :-
273 goal_name_arity(Goal, Name, Arity),
274 current_predicate(system:Name/Arity), 275 predicate_property(system:Goal, built_in),
276 !.
277
278
279 282
283verbose(Src) :-
284 \+ xoption(Src, silent(true)).
285
286:- thread_local
287 xref_input/2. 288
289
316
317xref_source(Source) :-
318 xref_source(Source, []).
319
320xref_source(Source, Options) :-
321 prolog_canonical_source(Source, Src),
322 ( last_modified(Source, Modified)
323 -> ( source(Src, Modified)
324 -> true
325 ; xref_clean(Src),
326 assert(source(Src, Modified)),
327 do_xref(Src, Options)
328 )
329 ; xref_clean(Src),
330 get_time(Now),
331 assert(source(Src, Now)),
332 do_xref(Src, Options)
333 ).
334
335do_xref(Src, Options) :-
336 must_be(list, Options),
337 setup_call_cleanup(
338 xref_setup(Src, In, Options, State),
339 collect(Src, Src, In, Options),
340 xref_cleanup(State)).
341
342last_modified(Source, Modified) :-
343 prolog:xref_source_time(Source, Modified),
344 !.
345last_modified(Source, Modified) :-
346 atom(Source),
347 \+ is_global_url(Source),
348 exists_file(Source),
349 time_file(Source, Modified).
350
351is_global_url(File) :-
352 sub_atom(File, B, _, _, '://'),
353 !,
354 B > 1,
355 sub_atom(File, 0, B, _, Scheme),
356 atom_codes(Scheme, Codes),
357 maplist(between(0'a, 0'z), Codes).
358
359xref_setup(Src, In, Options, state(CleanIn, Dialect, Xref, [SRef|HRefs])) :-
360 maplist(assert_option(Src), Options),
361 assert_default_options(Src),
362 current_prolog_flag(emulated_dialect, Dialect),
363 ( option(stream(Stream), Options)
364 -> In = Stream,
365 CleanIn = true
366 ; prolog_open_source(Src, In),
367 CleanIn = prolog_close_source(In)
368 ),
369 set_initial_mode(In, Options),
370 asserta(xref_input(Src, In), SRef),
371 set_xref(Xref),
372 ( verbose(Src)
373 -> HRefs = []
374 ; asserta((user:thread_message_hook(_,Level,_) :-
375 hide_message(Level)),
376 Ref),
377 HRefs = [Ref]
378 ).
379
380hide_message(warning).
381hide_message(error).
382hide_message(informational).
383
384assert_option(_, Var) :-
385 var(Var),
386 !,
387 instantiation_error(Var).
388assert_option(Src, silent(Boolean)) :-
389 !,
390 must_be(boolean, Boolean),
391 assert(xoption(Src, silent(Boolean))).
392assert_option(Src, register_called(Which)) :-
393 !,
394 must_be(oneof([all,non_iso,non_built_in]), Which),
395 assert(xoption(Src, register_called(Which))).
396assert_option(Src, comments(CommentHandling)) :-
397 !,
398 must_be(oneof([store,collect,ignore]), CommentHandling),
399 assert(xoption(Src, comments(CommentHandling))).
400assert_option(Src, module(Module)) :-
401 !,
402 must_be(atom, Module),
403 assert(xoption(Src, module(Module))).
404assert_option(Src, process_include(Boolean)) :-
405 !,
406 must_be(boolean, Boolean),
407 assert(xoption(Src, process_include(Boolean))).
408assert_option(_, _).
409
410assert_default_options(Src) :-
411 ( xref_option_default(Opt),
412 generalise_term(Opt, Gen),
413 ( xoption(Src, Gen)
414 -> true
415 ; assertz(xoption(Src, Opt))
416 ),
417 fail
418 ; true
419 ).
420
421xref_option_default(silent(false)).
422xref_option_default(register_called(non_built_in)).
423xref_option_default(comments(collect)).
424xref_option_default(process_include(true)).
425
429
430xref_cleanup(state(CleanIn, Dialect, Xref, Refs)) :-
431 call(CleanIn),
432 set_prolog_flag(emulated_dialect, Dialect),
433 set_prolog_flag(xref, Xref),
434 maplist(erase, Refs).
435
436set_xref(Xref) :-
437 current_prolog_flag(xref, Xref),
438 set_prolog_flag(xref, true).
439
440:- meta_predicate
441 with_xref(0). 442
443with_xref(Goal) :-
444 setup_call_cleanup(
445 push_prolog_flag(xref, true),
446 Goal,
447 pop_prolog_flag(xref)).
448
449
456
457set_initial_mode(_Stream, Options) :-
458 option(module(Module), Options),
459 !,
460 '$set_source_module'(Module).
461set_initial_mode(Stream, _) :-
462 stream_property(Stream, file_name(Path)),
463 source_file_property(Path, load_context(M, _, Opts)),
464 !,
465 '$set_source_module'(M),
466 ( option(dialect(Dialect), Opts)
467 -> expects_dialect(Dialect)
468 ; true
469 ).
470set_initial_mode(_, _) :-
471 '$set_source_module'(user).
472
476
477xref_input_stream(Stream) :-
478 xref_input(_, Var),
479 !,
480 Stream = Var.
481
486
487xref_push_op(Src, P, T, N0) :-
488 '$current_source_module'(M0),
489 strip_module(M0:N0, M, N),
490 ( is_list(N),
491 N \== []
492 -> maplist(push_op(Src, P, T, M), N)
493 ; push_op(Src, P, T, M, N)
494 ).
495
496push_op(Src, P, T, M0, N0) :-
497 strip_module(M0:N0, M, N),
498 Name = M:N,
499 valid_op(op(P,T,Name)),
500 push_op(P, T, Name),
501 assert_op(Src, op(P,T,Name)),
502 debug(xref(op), ':- ~w.', [op(P,T,Name)]).
503
504valid_op(op(P,T,M:N)) :-
505 atom(M),
506 valid_op_name(N),
507 integer(P),
508 between(0, 1200, P),
509 atom(T),
510 op_type(T).
511
512valid_op_name(N) :-
513 atom(N),
514 !.
515valid_op_name(N) :-
516 N == [].
517
518op_type(xf).
519op_type(yf).
520op_type(fx).
521op_type(fy).
522op_type(xfx).
523op_type(xfy).
524op_type(yfx).
525
529
530xref_set_prolog_flag(Flag, Value, Src, Line) :-
531 atom(Flag),
532 !,
533 assertz(xflag(Flag, Value, Src, Line)).
534xref_set_prolog_flag(_, _, _, _).
535
539
540xref_clean(Source) :-
541 prolog_canonical_source(Source, Src),
542 retractall(called(_, Src, _Origin, _Cond, _Line)),
543 retractall(dynamic(_, Src, Line)),
544 retractall(multifile(_, Src, Line)),
545 retractall(public(_, Src, Line)),
546 retractall(declared(_, _, Src, Line)),
547 retractall(defined(_, Src, Line)),
548 retractall(meta_goal(_, _, Src)),
549 retractall(foreign(_, Src, Line)),
550 retractall(constraint(_, Src, Line)),
551 retractall(imported(_, Src, _From)),
552 retractall(exported(_, Src)),
553 retractall(uses_file(_, Src, _)),
554 retractall(xmodule(_, Src)),
555 retractall(xop(Src, _)),
556 retractall(grammar_rule(_, Src)),
557 retractall(xoption(Src, _)),
558 retractall(xflag(_Name, _Value, Src, Line)),
559 retractall(source(Src, _)),
560 retractall(used_class(_, Src)),
561 retractall(defined_class(_, _, _, Src, _)),
562 retractall(mode(_, Src)),
563 retractall(module_comment(Src, _, _)),
564 retractall(pred_comment(_, Src, _, _)),
565 retractall(pred_comment_link(_, Src, _)),
566 retractall(pred_mode(_, Src, _)),
567 retractall(object_comment(_, Src, _, _)),
568 retractall(object_signature(_, Src, _)).
569
570
571 574
578
579xref_current_source(Source) :-
580 source(Source, _Time).
581
582
586
587xref_done(Source, Time) :-
588 prolog_canonical_source(Source, Src),
589 source(Src, Time).
590
591
610
611xref_called(Source, Called, By) :-
612 xref_called(Source, Called, By, _).
613
614xref_called(Source, Called, By, Cond) :-
615 canonical_source(Source, Src),
616 distinct(Called-By, called(Called, Src, By, Cond, _)).
617
618xref_called(Source, Called, By, Cond, Line) :-
619 canonical_source(Source, Src),
620 called(Called, Src, By, Cond, Line).
621
641
642xref_defined(Source, Called, How) :-
643 nonvar(Source),
644 !,
645 canonical_source(Source, Src),
646 xref_defined2(How, Src, Called).
647xref_defined(Source, Called, How) :-
648 xref_defined2(How, Src, Called),
649 canonical_source(Source, Src).
650
651xref_defined2(dynamic(Line), Src, Called) :-
652 dynamic(Called, Src, Line).
653xref_defined2(thread_local(Line), Src, Called) :-
654 thread_local(Called, Src, Line).
655xref_defined2(multifile(Line), Src, Called) :-
656 multifile(Called, Src, Line).
657xref_defined2(public(Line), Src, Called) :-
658 public(Called, Src, Line).
659xref_defined2(local(Line), Src, Called) :-
660 defined(Called, Src, Line).
661xref_defined2(foreign(Line), Src, Called) :-
662 foreign(Called, Src, Line).
663xref_defined2(constraint(Line), Src, Called) :-
664 ( constraint(Called, Src, Line)
665 -> true
666 ; declared(Called, chr_constraint, Src, Line)
667 ).
668xref_defined2(imported(From), Src, Called) :-
669 imported(Called, Src, From).
670xref_defined2(dcg, Src, Called) :-
671 grammar_rule(Called, Src).
672
673
678
679xref_definition_line(local(Line), Line).
680xref_definition_line(dynamic(Line), Line).
681xref_definition_line(thread_local(Line), Line).
682xref_definition_line(multifile(Line), Line).
683xref_definition_line(public(Line), Line).
684xref_definition_line(constraint(Line), Line).
685xref_definition_line(foreign(Line), Line).
686
687
691
692xref_exported(Source, Called) :-
693 prolog_canonical_source(Source, Src),
694 exported(Called, Src).
695
699
700xref_module(Source, Module) :-
701 nonvar(Source),
702 !,
703 prolog_canonical_source(Source, Src),
704 xmodule(Module, Src).
705xref_module(Source, Module) :-
706 xmodule(Module, Src),
707 prolog_canonical_source(Source, Src).
708
716
717xref_uses_file(Source, Spec, Path) :-
718 prolog_canonical_source(Source, Src),
719 uses_file(Spec, Src, Path).
720
728
729xref_op(Source, Op) :-
730 prolog_canonical_source(Source, Src),
731 xop(Src, Op).
732
738
739xref_prolog_flag(Source, Flag, Value, Line) :-
740 prolog_canonical_source(Source, Src),
741 xflag(Flag, Value, Src, Line).
742
743xref_built_in(Head) :-
744 system_predicate(Head).
745
746xref_used_class(Source, Class) :-
747 prolog_canonical_source(Source, Src),
748 used_class(Class, Src).
749
750xref_defined_class(Source, Class, local(Line, Super, Summary)) :-
751 prolog_canonical_source(Source, Src),
752 defined_class(Class, Super, Summary, Src, Line),
753 integer(Line),
754 !.
755xref_defined_class(Source, Class, file(File)) :-
756 prolog_canonical_source(Source, Src),
757 defined_class(Class, _, _, Src, file(File)).
758
759:- thread_local
760 current_cond/1,
761 source_line/1,
762 current_test_unit/2. 763
764current_source_line(Line) :-
765 source_line(Var),
766 !,
767 Line = Var.
768
774
775collect(Src, File, In, Options) :-
776 ( Src == File
777 -> SrcSpec = Line
778 ; SrcSpec = (File:Line)
779 ),
780 ( current_prolog_flag(xref_store_comments, OldStore)
781 -> true
782 ; OldStore = false
783 ),
784 option(comments(CommentHandling), Options, collect),
785 ( CommentHandling == ignore
786 -> CommentOptions = [],
787 Comments = []
788 ; CommentHandling == store
789 -> CommentOptions = [ process_comment(true) ],
790 Comments = [],
791 set_prolog_flag(xref_store_comments, true)
792 ; CommentOptions = [ comments(Comments) ]
793 ),
794 repeat,
795 E = error(_,_),
796 catch(prolog_read_source_term(
797 In, Term, Expanded,
798 [ term_position(TermPos),
799 variable_names(VarNames)
800 | CommentOptions
801 ]),
802 E, report_syntax_error(E, Src, [])),
803 update_condition(Term),
804 stream_position_data(line_count, TermPos, Line),
805 setup_call_cleanup(
806 asserta(source_line(SrcSpec), Ref),
807 catch(process(Expanded, Comments, Term, VarNames, TermPos,
808 Src, EOF),
809 E, print_message(error, E)),
810 erase(Ref)),
811 EOF == true,
812 !,
813 set_prolog_flag(xref_store_comments, OldStore).
814
815report_syntax_error(_, _, Options) :-
816 option(silent(true), Options),
817 !,
818 fail.
819report_syntax_error(E, Src, _Options) :-
820 ( verbose(Src)
821 -> print_message(error, E)
822 ; true
823 ),
824 fail.
825
829
830update_condition((:-Directive)) :-
831 !,
832 update_cond(Directive).
833update_condition(_).
834
835update_cond(if(Cond)) :-
836 !,
837 asserta(current_cond(Cond)).
838update_cond(else) :-
839 retract(current_cond(C0)),
840 !,
841 assert(current_cond(\+C0)).
842update_cond(elif(Cond)) :-
843 retract(current_cond(C0)),
844 !,
845 assert(current_cond((\+C0,Cond))).
846update_cond(endif) :-
847 retract(current_cond(_)),
848 !.
849update_cond(_).
850
855
856current_condition(Condition) :-
857 \+ current_cond(_),
858 !,
859 Condition = true.
860current_condition(Condition) :-
861 findall(C, current_cond(C), List),
862 list_to_conj(List, Condition).
863
864list_to_conj([], true).
865list_to_conj([C], C) :- !.
866list_to_conj([H|T], (H,C)) :-
867 list_to_conj(T, C).
868
869
870 873
886
887process(Expanded, Comments, Term0, VarNames, TermPos, Src, EOF) :-
888 is_list(Expanded), 889 !,
890 ( member(Term, Expanded),
891 process(Term, Term0, Src),
892 Term == end_of_file
893 -> EOF = true
894 ; EOF = false
895 ),
896 xref_comments(Comments, TermPos, Term0, VarNames, Src).
897process(end_of_file, _, _, _, _, _, true) :-
898 !.
899process(Term, Comments, Term0, VarNames, TermPos, Src, false) :-
900 process(Term, Term0, Src),
901 xref_comments(Comments, TermPos, Term0, VarNames, Src).
902
904
905process(_, Term0, _) :-
906 ignore_raw_term(Term0),
907 !.
908process(Head :- Body, Head0 --> _, Src) :-
909 pi_head(F/A, Head),
910 pi_head(F/A0, Head0),
911 A =:= A0 + 2,
912 !,
913 assert_grammar_rule(Src, Head),
914 process((Head :- Body), Src).
915process(Term, _Term0, Src) :-
916 process(Term, Src).
917
918ignore_raw_term((:- predicate_options(_,_,_))).
919
921
922process(Var, _) :-
923 var(Var),
924 !. 925process(end_of_file, _) :- !.
926process((:- Directive), Src) :-
927 !,
928 process_directive(Directive, Src),
929 !.
930process((?- Directive), Src) :-
931 !,
932 process_directive(Directive, Src),
933 !.
934process((Head :- Body), Src) :-
935 !,
936 assert_defined(Src, Head),
937 process_body(Body, Head, Src).
938process((Left => Body), Src) :-
939 !,
940 ( nonvar(Left),
941 Left = (Head, Guard)
942 -> assert_defined(Src, Head),
943 process_body(Guard, Head, Src),
944 process_body(Body, Head, Src)
945 ; assert_defined(Src, Left),
946 process_body(Body, Left, Src)
947 ).
948process(?=>(Head, Body), Src) :-
949 !,
950 assert_defined(Src, Head),
951 process_body(Body, Head, Src).
952process('$source_location'(_File, _Line):Clause, Src) :-
953 !,
954 process(Clause, Src).
955process(Term, Src) :-
956 process_chr(Term, Src),
957 !.
958process(M:(Head :- Body), Src) :-
959 !,
960 process((M:Head :- M:Body), Src).
961process(Head, Src) :-
962 assert_defined(Src, Head).
963
964
965 968
974
([], _Pos, _Term, _VarNames, _Src).
976:- if(current_predicate(parse_comment/5)). 977xref_comments([Pos-Comment|T], TermPos, Term, VarNames, Src) :-
978 ( Pos @> TermPos 979 -> true
980 ; stream_position_data(line_count, Pos, Line),
981 FilePos = Src:Line,
982 ( last_comment(T, TermPos)
983 -> CTerm = Term
984 ; true
985 ),
986 ( parse_comment(Comment, FilePos, CTerm, VarNames, Parsed)
987 -> assert_comments(Parsed, Src)
988 ; true
989 ),
990 xref_comments(T, TermPos, Term, VarNames, Src)
991 ).
992
([], _).
994last_comment([Pos-_|_], TermPos) :-
995 Pos @> TermPos.
996
([], _).
998assert_comments([H|T], Src) :-
999 assert_comment(H, Src),
1000 assert_comments(T, Src).
1001
(section(Id, Title, Comment), Src) :-
1003 ( Id = module(_)
1004 -> assertz(module_comment(Src, Title, Comment))
1005 ; true
1006 ).
1007assert_comment(predicate(PI, Summary, Comment), Src) :-
1008 pi_to_head(PI, Src, Head),
1009 assertz(pred_comment(Head, Src, Summary, Comment)).
1010assert_comment(link(PI, PITo), Src) :-
1011 pi_to_head(PI, Src, Head),
1012 pi_to_head(PITo, Src, HeadTo),
1013 assertz(pred_comment_link(Head, Src, HeadTo)).
1014assert_comment(mode(Head, Det), Src) :-
1015 assertz(pred_mode(Head, Src, Det)).
1016assert_comment(object(Object, Summary, Comment), Src) :-
1017 assertz(object_comment(Object, Src, Summary, Comment)).
1018assert_comment(signature(Object, Signature), Src) :-
1019 assertz(object_signature(Object, Src, Signature)).
1020
1021pi_to_head(PI, Src, Head) :-
1022 pi_to_head(PI, Head0),
1023 ( Head0 = _:_
1024 -> strip_module(Head0, M, Plain),
1025 ( xmodule(M, Src)
1026 -> Head = Plain
1027 ; Head = M:Plain
1028 )
1029 ; Head = Head0
1030 ).
1031:- endif. 1032
1036
(Source, Title, Comment) :-
1038 canonical_source(Source, Src),
1039 module_comment(Src, Title, Comment).
1040
1044
(Source, Head, Summary, Comment) :-
1046 canonical_source(Source, Src),
1047 ( pred_comment(Head, Src, Summary, Comment)
1048 ; pred_comment_link(Head, Src, HeadTo),
1049 pred_comment(HeadTo, Src, Summary, Comment)
1050 ).
1051
1057
(Source, Object, Summary, Comment) :-
1059 canonical_source(Source, Src),
1060 object_comment(Object, Src, Summary, Comment).
1061
1066
1067xref_object_signature(Source, Object, Signature) :-
1068 canonical_source(Source, Src),
1069 object_signature(Object, Src, Signature).
1070
1075
1076xref_mode(Source, Mode, Det) :-
1077 canonical_source(Source, Src),
1078 pred_mode(Mode, Src, Det).
1079
1084
1085xref_option(Source, Option) :-
1086 canonical_source(Source, Src),
1087 xoption(Src, Option).
1088
1089
1090 1093
1094process_directive(Var, _) :-
1095 var(Var),
1096 !. 1097process_directive(Dir, _Src) :-
1098 debug(xref(directive), 'Processing :- ~q', [Dir]),
1099 fail.
1100process_directive((A,B), Src) :- 1101 !,
1102 process_directive(A, Src), 1103 process_directive(B, Src).
1104process_directive(List, Src) :-
1105 is_list(List),
1106 !,
1107 process_directive(consult(List), Src).
1108process_directive(use_module(File, Import), Src) :-
1109 process_use_module2(File, Import, Src, false).
1110process_directive(autoload(File, Import), Src) :-
1111 process_use_module2(File, Import, Src, false).
1112process_directive(require(Import), Src) :-
1113 process_requires(Import, Src).
1114process_directive(expects_dialect(Dialect), Src) :-
1115 process_directive(use_module(library(dialect/Dialect)), Src),
1116 expects_dialect(Dialect).
1117process_directive(reexport(File, Import), Src) :-
1118 process_use_module2(File, Import, Src, true).
1119process_directive(reexport(Modules), Src) :-
1120 process_use_module(Modules, Src, true).
1121process_directive(autoload(Modules), Src) :-
1122 process_use_module(Modules, Src, false).
1123process_directive(use_module(Modules), Src) :-
1124 process_use_module(Modules, Src, false).
1125process_directive(consult(Modules), Src) :-
1126 process_use_module(Modules, Src, false).
1127process_directive(ensure_loaded(Modules), Src) :-
1128 process_use_module(Modules, Src, false).
1129process_directive(load_files(Files, _Options), Src) :-
1130 process_use_module(Files, Src, false).
1131process_directive(include(Files), Src) :-
1132 process_include(Files, Src).
1133process_directive(dynamic(Dynamic), Src) :-
1134 process_predicates(assert_dynamic, Dynamic, Src).
1135process_directive(dynamic(Dynamic, _Options), Src) :-
1136 process_predicates(assert_dynamic, Dynamic, Src).
1137process_directive(thread_local(Dynamic), Src) :-
1138 process_predicates(assert_thread_local, Dynamic, Src).
1139process_directive(multifile(Dynamic), Src) :-
1140 process_predicates(assert_multifile, Dynamic, Src).
1141process_directive(public(Public), Src) :-
1142 process_predicates(assert_public, Public, Src).
1143process_directive(export(Export), Src) :-
1144 process_predicates(assert_export, Export, Src).
1145process_directive(import(Import), Src) :-
1146 process_import(Import, Src).
1147process_directive(module(Module, Export), Src) :-
1148 assert_module(Src, Module),
1149 assert_module_export(Src, Export).
1150process_directive(module(Module, Export, Import), Src) :-
1151 assert_module(Src, Module),
1152 assert_module_export(Src, Export),
1153 assert_module3(Import, Src).
1154process_directive(begin_tests(Unit, _Options), Src) :-
1155 enter_test_unit(Unit, Src).
1156process_directive(begin_tests(Unit), Src) :-
1157 enter_test_unit(Unit, Src).
1158process_directive(end_tests(Unit), Src) :-
1159 leave_test_unit(Unit, Src).
1160process_directive('$set_source_module'(system), Src) :-
1161 assert_module(Src, system). 1162process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :-
1163 assert_defined_class(Src, Name, Meta, Super, Doc).
1164process_directive(pce_autoload(Name, From), Src) :-
1165 assert_defined_class(Src, Name, imported_from(From)).
1166
1167process_directive(op(P, A, N), Src) :-
1168 xref_push_op(Src, P, A, N).
1169process_directive(set_prolog_flag(Flag, Value), Src) :-
1170 ( Flag == character_escapes
1171 -> set_prolog_flag(character_escapes, Value)
1172 ; true
1173 ),
1174 current_source_line(Line),
1175 xref_set_prolog_flag(Flag, Value, Src, Line).
1176process_directive(style_check(X), _) :-
1177 style_check(X).
1178process_directive(encoding(Enc), _) :-
1179 ( xref_input_stream(Stream)
1180 -> catch(set_stream(Stream, encoding(Enc)), error(_,_), true)
1181 ; true 1182 ).
1183process_directive(pce_expansion:push_compile_operators, _) :-
1184 '$current_source_module'(SM),
1185 call(pce_expansion:push_compile_operators(SM)). 1186process_directive(pce_expansion:pop_compile_operators, _) :-
1187 call(pce_expansion:pop_compile_operators).
1188process_directive(meta_predicate(Meta), Src) :-
1189 process_meta_predicate(Meta, Src).
1190process_directive(arithmetic_function(FSpec), Src) :-
1191 arith_callable(FSpec, Goal),
1192 !,
1193 current_source_line(Line),
1194 assert_called(Src, '<directive>'(Line), Goal, Line).
1195process_directive(format_predicate(_, Goal), Src) :-
1196 !,
1197 current_source_line(Line),
1198 assert_called(Src, '<directive>'(Line), Goal, Line).
1199process_directive(if(Cond), Src) :-
1200 !,
1201 current_source_line(Line),
1202 assert_called(Src, '<directive>'(Line), Cond, Line).
1203process_directive(elif(Cond), Src) :-
1204 !,
1205 current_source_line(Line),
1206 assert_called(Src, '<directive>'(Line), Cond, Line).
1207process_directive(else, _) :- !.
1208process_directive(endif, _) :- !.
1209process_directive(Goal, Src) :-
1210 current_source_line(Line),
1211 process_body(Goal, '<directive>'(Line), Src).
1212
1216
1217process_meta_predicate((A,B), Src) :-
1218 !,
1219 process_meta_predicate(A, Src),
1220 process_meta_predicate(B, Src).
1221process_meta_predicate(Decl, Src) :-
1222 process_meta_head(Src, Decl).
1223
1224process_meta_head(Src, Decl) :- 1225 compound(Decl),
1226 compound_name_arity(Decl, Name, Arity),
1227 compound_name_arity(Head, Name, Arity),
1228 meta_args(1, Arity, Decl, Head, Meta),
1229 ( ( prolog:meta_goal(Head, _)
1230 ; prolog:called_by(Head, _, _, _)
1231 ; prolog:called_by(Head, _)
1232 ; meta_goal(Head, Meta, _Src)
1233 )
1234 -> true
1235 ; warn_late_meta_predicate(Decl, Src),
1236 retractall(meta_goal(Head, _, Src)),
1237 assert(meta_goal(Head, Meta, Src))
1238 ).
1239
1240meta_args(I, Arity, _, _, []) :-
1241 I > Arity,
1242 !.
1243meta_args(I, Arity, Decl, Head, [H|T]) :- 1244 arg(I, Decl, 0),
1245 !,
1246 arg(I, Head, H),
1247 I2 is I + 1,
1248 meta_args(I2, Arity, Decl, Head, T).
1249meta_args(I, Arity, Decl, Head, [H|T]) :- 1250 arg(I, Decl, ^),
1251 !,
1252 arg(I, Head, EH),
1253 setof_goal(EH, H),
1254 I2 is I + 1,
1255 meta_args(I2, Arity, Decl, Head, T).
1256meta_args(I, Arity, Decl, Head, [//(H)|T]) :-
1257 arg(I, Decl, //),
1258 !,
1259 arg(I, Head, H),
1260 I2 is I + 1,
1261 meta_args(I2, Arity, Decl, Head, T).
1262meta_args(I, Arity, Decl, Head, [H+A|T]) :- 1263 arg(I, Decl, A),
1264 integer(A), A > 0,
1265 !,
1266 arg(I, Head, H),
1267 I2 is I + 1,
1268 meta_args(I2, Arity, Decl, Head, T).
1269meta_args(I, Arity, Decl, Head, Meta) :-
1270 I2 is I + 1,
1271 meta_args(I2, Arity, Decl, Head, Meta).
1272
1273
1274warn_late_meta_predicate(Decl, Src) :-
1275 xref_called(Src, Decl, By),
1276 !,
1277 print_message(warning, meta_predicate_after_call(Decl, By)).
1278warn_late_meta_predicate(_, _).
1279
1280
1281 1284
1291
1292xref_meta(Source, Head, Called) :-
1293 canonical_source(Source, Src),
1294 xref_meta_src(Head, Called, Src).
1295
1308
1309xref_meta_src(Head, Called, Src) :-
1310 meta_goal(Head, Called, Src),
1311 !.
1312xref_meta_src(Head, Called, _) :-
1313 xref_meta(Head, Called),
1314 !.
1315xref_meta_src(Head, Called, _) :-
1316 compound(Head),
1317 compound_name_arity(Head, Name, Arity),
1318 apply_pred(Name),
1319 Arity > 5,
1320 !,
1321 Extra is Arity - 1,
1322 arg(1, Head, G),
1323 Called = [G+Extra].
1324xref_meta_src(Head, Called, _) :-
1325 with_xref(predicate_property('$xref_tmp':Head, meta_predicate(Meta))),
1326 !,
1327 Meta =.. [_|Args],
1328 meta_args(Args, 1, Head, Called).
1329
1330meta_args([], _, _, []).
1331meta_args([H0|T0], I, Head, [H|T]) :-
1332 xargs(H0, N),
1333 !,
1334 arg(I, Head, A),
1335 ( N == 0
1336 -> H = A
1337 ; H = (A+N)
1338 ),
1339 I2 is I+1,
1340 meta_args(T0, I2, Head, T).
1341meta_args([_|T0], I, Head, T) :-
1342 I2 is I+1,
1343 meta_args(T0, I2, Head, T).
1344
1345xargs(N, N) :- integer(N), !.
1346xargs(//, 2).
1347xargs(^, 0).
1348
1349apply_pred(call). 1350apply_pred(maplist). 1351
1352xref_meta((A, B), [A, B]).
1353xref_meta((A; B), [A, B]).
1354xref_meta((A| B), [A, B]).
1355xref_meta((A -> B), [A, B]).
1356xref_meta((A *-> B), [A, B]).
1357xref_meta(findall(_V,G,_L), [G]).
1358xref_meta(findall(_V,G,_L,_T), [G]).
1359xref_meta(findnsols(_N,_V,G,_L), [G]).
1360xref_meta(findnsols(_N,_V,G,_L,_T), [G]).
1361xref_meta(setof(_V, EG, _L), [G]) :-
1362 setof_goal(EG, G).
1363xref_meta(bagof(_V, EG, _L), [G]) :-
1364 setof_goal(EG, G).
1365xref_meta(aggregate(_V, EG, _L), [G]) :-
1366 setof_goal(EG, G).
1367xref_meta(aggregate(_V, _D, EG, _L), [G]) :-
1368 setof_goal(EG, G).
1369xref_meta(forall(A, B), [A, B]).
1370xref_meta(maplist(G,_), [G+1]).
1371xref_meta(maplist(G,_,_), [G+2]).
1372xref_meta(maplist(G,_,_,_), [G+3]).
1373xref_meta(maplist(G,_,_,_,_), [G+4]).
1374xref_meta(map_list_to_pairs(G,_,_), [G+2]).
1375xref_meta(map_assoc(G, _), [G+1]).
1376xref_meta(map_assoc(G, _, _), [G+2]).
1377xref_meta(checklist(G, _L), [G+1]).
1378xref_meta(sublist(G, _, _), [G+1]).
1379xref_meta(include(G, _, _), [G+1]).
1380xref_meta(exclude(G, _, _), [G+1]).
1381xref_meta(partition(G, _, _, _, _), [G+2]).
1382xref_meta(partition(G, _, _, _),[G+1]).
1383xref_meta(call(G), [G]).
1384xref_meta(call(G, _), [G+1]).
1385xref_meta(call(G, _, _), [G+2]).
1386xref_meta(call(G, _, _, _), [G+3]).
1387xref_meta(call(G, _, _, _, _), [G+4]).
1388xref_meta(not(G), [G]).
1389xref_meta(notrace(G), [G]).
1390xref_meta('$notrace'(G), [G]).
1391xref_meta(\+(G), [G]).
1392xref_meta(ignore(G), [G]).
1393xref_meta(once(G), [G]).
1394xref_meta(initialization(G), [G]).
1395xref_meta(initialization(G,_), [G]).
1396xref_meta(retract(Rule), [G]) :- head_of(Rule, G).
1397xref_meta(clause(G, _), [G]).
1398xref_meta(clause(G, _, _), [G]).
1399xref_meta(phrase(G, _A), [//(G)]).
1400xref_meta(phrase(G, _A, _R), [//(G)]).
1401xref_meta(call_dcg(G, _A, _R), [//(G)]).
1402xref_meta(phrase_from_file(G,_),[//(G)]).
1403xref_meta(catch(A, _, B), [A, B]).
1404xref_meta(catch_with_backtrace(A, _, B), [A, B]).
1405xref_meta(thread_create(A,_,_), [A]).
1406xref_meta(thread_create(A,_), [A]).
1407xref_meta(thread_signal(_,A), [A]).
1408xref_meta(thread_idle(A,_), [A]).
1409xref_meta(thread_at_exit(A), [A]).
1410xref_meta(thread_initialization(A), [A]).
1411xref_meta(engine_create(_,A,_), [A]).
1412xref_meta(engine_create(_,A,_,_), [A]).
1413xref_meta(transaction(A), [A]).
1414xref_meta(transaction(A,B,_), [A,B]).
1415xref_meta(snapshot(A), [A]).
1416xref_meta(predsort(A,_,_), [A+3]).
1417xref_meta(call_cleanup(A, B), [A, B]).
1418xref_meta(call_cleanup(A, _, B),[A, B]).
1419xref_meta(setup_call_cleanup(A, B, C),[A, B, C]).
1420xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]).
1421xref_meta(call_residue_vars(A,_), [A]).
1422xref_meta(with_mutex(_,A), [A]).
1423xref_meta(assume(G), [G]). 1424xref_meta(assertion(G), [G]). 1425xref_meta(freeze(_, G), [G]).
1426xref_meta(when(C, A), [C, A]).
1427xref_meta(time(G), [G]). 1428xref_meta(call_time(G, _), [G]). 1429xref_meta(call_time(G, _, _), [G]). 1430xref_meta(profile(G), [G]).
1431xref_meta(at_halt(G), [G]).
1432xref_meta(call_with_time_limit(_, G), [G]).
1433xref_meta(call_with_depth_limit(G, _, _), [G]).
1434xref_meta(call_with_inference_limit(G, _, _), [G]).
1435xref_meta(alarm(_, G, _), [G]).
1436xref_meta(alarm(_, G, _, _), [G]).
1437xref_meta('$add_directive_wic'(G), [G]).
1438xref_meta(with_output_to(_, G), [G]).
1439xref_meta(if(G), [G]).
1440xref_meta(elif(G), [G]).
1441xref_meta(meta_options(G,_,_), [G+1]).
1442xref_meta(on_signal(_,_,H), [H+1]) :- H \== default.
1443xref_meta(distinct(G), [G]). 1444xref_meta(distinct(_, G), [G]).
1445xref_meta(order_by(_, G), [G]).
1446xref_meta(limit(_, G), [G]).
1447xref_meta(offset(_, G), [G]).
1448xref_meta(reset(G,_,_), [G]).
1449xref_meta(prolog_listen(Ev,G), [G+N]) :- event_xargs(Ev, N).
1450xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N).
1451xref_meta(tnot(G), [G]).
1452xref_meta(not_exists(G), [G]).
1453xref_meta(with_tty_raw(G), [G]).
1454xref_meta(residual_goals(G), [G+2]).
1455
1456 1457xref_meta(pce_global(_, new(_)), _) :- !, fail.
1458xref_meta(pce_global(_, B), [B+1]).
1459xref_meta(ifmaintainer(G), [G]). 1460xref_meta(listen(_, G), [G]). 1461xref_meta(listen(_, _, G), [G]).
1462xref_meta(in_pce_thread(G), [G]).
1463
1464xref_meta(G, Meta) :- 1465 prolog:meta_goal(G, Meta).
1466xref_meta(G, Meta) :- 1467 meta_goal(G, Meta, _Src).
1468
1469setof_goal(EG, G) :-
1470 var(EG), !, G = EG.
1471setof_goal(_^EG, G) :-
1472 !,
1473 setof_goal(EG, G).
1474setof_goal(G, G).
1475
1476event_xargs(abort, 0).
1477event_xargs(erase, 1).
1478event_xargs(break, 3).
1479event_xargs(frame_finished, 1).
1480event_xargs(thread_exit, 1).
1481event_xargs(this_thread_exit, 0).
1482event_xargs(PI, 2) :- pi_to_head(PI, _).
1483
1487
1488head_of(Var, _) :-
1489 var(Var), !, fail.
1490head_of((Head :- _), Head).
1491head_of(Head, Head).
1492
1498
1499xref_hook(Hook) :-
1500 prolog:hook(Hook).
1501xref_hook(Hook) :-
1502 hook(Hook).
1503
1504
1505hook(attr_portray_hook(_,_)).
1506hook(attr_unify_hook(_,_)).
1507hook(attribute_goals(_,_,_)).
1508hook(goal_expansion(_,_)).
1509hook(term_expansion(_,_)).
1510hook(goal_expansion(_,_,_,_)).
1511hook(term_expansion(_,_,_,_)).
1512hook(resource(_,_,_)).
1513hook('$pred_option'(_,_,_,_)).
1514hook('$nowarn_autoload'(_,_)).
1515
1516hook(emacs_prolog_colours:goal_classification(_,_)).
1517hook(emacs_prolog_colours:goal_colours(_,_)).
1518hook(emacs_prolog_colours:identify(_,_)).
1519hook(emacs_prolog_colours:style(_,_)).
1520hook(emacs_prolog_colours:term_colours(_,_)).
1521hook(pce_principal:get_implementation(_,_,_,_)).
1522hook(pce_principal:pce_class(_,_,_,_,_,_)).
1523hook(pce_principal:pce_lazy_get_method(_,_,_)).
1524hook(pce_principal:pce_lazy_send_method(_,_,_)).
1525hook(pce_principal:pce_uses_template(_,_)).
1526hook(pce_principal:send_implementation(_,_,_)).
1527hook(predicate_options:option_decl(_,_,_)).
1528hook(prolog:debug_control_hook(_)).
1529hook(prolog:error_message(_,_,_)).
1530hook(prolog:expand_answer(_,_,_)).
1531hook(prolog:general_exception(_,_)).
1532hook(prolog:help_hook(_)).
1533hook(prolog:locate_clauses(_,_)).
1534hook(prolog:message(_,_,_)).
1535hook(prolog:message_context(_,_,_)).
1536hook(prolog:message_line_element(_,_)).
1537hook(prolog:message_location(_,_,_)).
1538hook(prolog:predicate_summary(_,_)).
1539hook(prolog:prolog_exception_hook(_,_,_,_,_)).
1540hook(prolog:residual_goals(_,_)).
1541hook(prolog_edit:load).
1542hook(prolog_edit:locate(_,_,_)).
1543hook(sandbox:safe_directive(_)).
1544hook(sandbox:safe_global_variable(_)).
1545hook(sandbox:safe_meta(_,_)).
1546hook(sandbox:safe_meta_predicate(_)).
1547hook(sandbox:safe_primitive(_)).
1548hook(sandbox:safe_prolog_flag(_,_)).
1549hook(shlib:unload_all_foreign_libraries).
1550hook(system:'$foreign_registered'(_, _)).
1551hook(user:exception(_,_,_)).
1552hook(user:expand_answer(_,_)).
1553hook(user:expand_query(_,_,_,_)).
1554hook(user:file_search_path(_,_)).
1555hook(user:library_directory(_)).
1556hook(user:message_hook(_,_,_)).
1557hook(prolog:message_action(_,_)).
1558hook(user:portray(_)).
1559hook(user:prolog_clause_name(_,_)).
1560hook(user:prolog_list_goal(_)).
1561hook(user:prolog_predicate_name(_,_)).
1562hook(user:prolog_trace_interception(_,_,_,_)).
1563
1567
1568arith_callable(Var, _) :-
1569 var(Var), !, fail.
1570arith_callable(Module:Spec, Module:Goal) :-
1571 !,
1572 arith_callable(Spec, Goal).
1573arith_callable(Name/Arity, Goal) :-
1574 PredArity is Arity + 1,
1575 functor(Goal, Name, PredArity).
1576
1585
1586process_body(Body, Origin, Src) :-
1587 forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
1588 true).
1589
1594
1595process_goal(Var, _, _, _) :-
1596 var(Var),
1597 !.
1598process_goal(_:Goal, _, _, _) :-
1599 var(Goal),
1600 !.
1601process_goal(Goal, Origin, Src, P) :-
1602 Goal = (_,_), 1603 !,
1604 phrase(conjunction(Goal), Goals),
1605 process_conjunction(Goals, Origin, Src, P).
1606process_goal(Goal, Origin, Src, _) :- 1607 Goal = (_;_), 1608 !,
1609 phrase(disjunction(Goal), Goals),
1610 forall(member(G, Goals),
1611 process_body(G, Origin, Src)).
1612process_goal(Goal, Origin, Src, P) :-
1613 ( ( xmodule(M, Src)
1614 -> true
1615 ; M = user
1616 ),
1617 pi_head(PI, M:Goal),
1618 ( current_predicate(PI),
1619 predicate_property(M:Goal, imported_from(IM))
1620 -> true
1621 ; PI = M:Name/Arity,
1622 '$find_library'(M, Name, Arity, IM, _Library)
1623 -> true
1624 ; IM = M
1625 ),
1626 prolog:called_by(Goal, IM, M, Called)
1627 ; prolog:called_by(Goal, Called)
1628 ),
1629 !,
1630 must_be(list, Called),
1631 current_source_line(Here),
1632 assert_called(Src, Origin, Goal, Here),
1633 process_called_list(Called, Origin, Src, P).
1634process_goal(Goal, Origin, Src, _) :-
1635 process_xpce_goal(Goal, Origin, Src),
1636 !.
1637process_goal(load_foreign_library(File), _Origin, Src, _) :-
1638 process_foreign(File, Src).
1639process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :-
1640 process_foreign(File, Src).
1641process_goal(use_foreign_library(File), _Origin, Src, _) :-
1642 process_foreign(File, Src).
1643process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :-
1644 process_foreign(File, Src).
1645process_goal(Goal, Origin, Src, P) :-
1646 xref_meta_src(Goal, Metas, Src),
1647 !,
1648 current_source_line(Here),
1649 assert_called(Src, Origin, Goal, Here),
1650 process_called_list(Metas, Origin, Src, P).
1651process_goal(Goal, Origin, Src, _) :-
1652 asserting_goal(Goal, Rule),
1653 !,
1654 current_source_line(Here),
1655 assert_called(Src, Origin, Goal, Here),
1656 process_assert(Rule, Origin, Src).
1657process_goal(Goal, Origin, Src, P) :-
1658 partial_evaluate(Goal, P),
1659 current_source_line(Here),
1660 assert_called(Src, Origin, Goal, Here).
1661
1662disjunction(Var) --> {var(Var), !}, [Var].
1663disjunction((A;B)) --> !, disjunction(A), disjunction(B).
1664disjunction(G) --> [G].
1665
1666conjunction(Var) --> {var(Var), !}, [Var].
1667conjunction((A,B)) --> !, conjunction(A), conjunction(B).
1668conjunction(G) --> [G].
1669
1670shares_vars(RVars, T) :-
1671 term_variables(T, TVars0),
1672 sort(TVars0, TVars),
1673 ord_intersect(RVars, TVars).
1674
1675process_conjunction([], _, _, _).
1676process_conjunction([Disj|Rest], Origin, Src, P) :-
1677 nonvar(Disj),
1678 Disj = (_;_),
1679 Rest \== [],
1680 !,
1681 phrase(disjunction(Disj), Goals),
1682 term_variables(Rest, RVars0),
1683 sort(RVars0, RVars),
1684 partition(shares_vars(RVars), Goals, Sharing, NonSHaring),
1685 forall(member(G, NonSHaring),
1686 process_body(G, Origin, Src)),
1687 ( Sharing == []
1688 -> true
1689 ; maplist(term_variables, Sharing, GVars0),
1690 append(GVars0, GVars1),
1691 sort(GVars1, GVars),
1692 ord_intersection(GVars, RVars, SVars),
1693 VT =.. [v|SVars],
1694 findall(VT,
1695 ( member(G, Sharing),
1696 process_goal(G, Origin, Src, PS),
1697 PS == true
1698 ),
1699 Alts0),
1700 ( Alts0 == []
1701 -> true
1702 ; ( true
1703 ; P = true,
1704 sort(Alts0, Alts1),
1705 variants(Alts1, 10, Alts),
1706 member(VT, Alts)
1707 )
1708 )
1709 ),
1710 process_conjunction(Rest, Origin, Src, P).
1711process_conjunction([H|T], Origin, Src, P) :-
1712 process_goal(H, Origin, Src, P),
1713 process_conjunction(T, Origin, Src, P).
1714
1715
1716process_called_list([], _, _, _).
1717process_called_list([H|T], Origin, Src, P) :-
1718 process_meta(H, Origin, Src, P),
1719 process_called_list(T, Origin, Src, P).
1720
1721process_meta(A+N, Origin, Src, P) :-
1722 !,
1723 ( extend(A, N, AX)
1724 -> process_goal(AX, Origin, Src, P)
1725 ; true
1726 ).
1727process_meta(//(A), Origin, Src, P) :-
1728 !,
1729 process_dcg_goal(A, Origin, Src, P).
1730process_meta(G, Origin, Src, P) :-
1731 process_goal(G, Origin, Src, P).
1732
1737
1738process_dcg_goal(Var, _, _, _) :-
1739 var(Var),
1740 !.
1741process_dcg_goal((A,B), Origin, Src, P) :-
1742 !,
1743 process_dcg_goal(A, Origin, Src, P),
1744 process_dcg_goal(B, Origin, Src, P).
1745process_dcg_goal((A;B), Origin, Src, P) :-
1746 !,
1747 process_dcg_goal(A, Origin, Src, P),
1748 process_dcg_goal(B, Origin, Src, P).
1749process_dcg_goal((A|B), Origin, Src, P) :-
1750 !,
1751 process_dcg_goal(A, Origin, Src, P),
1752 process_dcg_goal(B, Origin, Src, P).
1753process_dcg_goal((A->B), Origin, Src, P) :-
1754 !,
1755 process_dcg_goal(A, Origin, Src, P),
1756 process_dcg_goal(B, Origin, Src, P).
1757process_dcg_goal((A*->B), Origin, Src, P) :-
1758 !,
1759 process_dcg_goal(A, Origin, Src, P),
1760 process_dcg_goal(B, Origin, Src, P).
1761process_dcg_goal({Goal}, Origin, Src, P) :-
1762 !,
1763 process_goal(Goal, Origin, Src, P).
1764process_dcg_goal(List, _Origin, _Src, _) :-
1765 is_list(List),
1766 !. 1767process_dcg_goal(List, _Origin, _Src, _) :-
1768 string(List),
1769 !. 1770process_dcg_goal(Callable, Origin, Src, P) :-
1771 extend(Callable, 2, Goal),
1772 !,
1773 process_goal(Goal, Origin, Src, P).
1774process_dcg_goal(_, _, _, _).
1775
1776
1777extend(Var, _, _) :-
1778 var(Var), !, fail.
1779extend(M:G, N, M:GX) :-
1780 !,
1781 callable(G),
1782 extend(G, N, GX).
1783extend(G, N, GX) :-
1784 ( N =:= 0
1785 -> GX = G
1786 ; compound(G)
1787 -> compound_name_arguments(G, Name, Args),
1788 length(Rest, N),
1789 append(Args, Rest, NArgs),
1790 compound_name_arguments(GX, Name, NArgs)
1791 ; atom(G)
1792 -> length(NArgs, N),
1793 compound_name_arguments(GX, G, NArgs)
1794 ).
1795
1796asserting_goal(assert(Rule), Rule).
1797asserting_goal(asserta(Rule), Rule).
1798asserting_goal(assertz(Rule), Rule).
1799asserting_goal(assert(Rule,_), Rule).
1800asserting_goal(asserta(Rule,_), Rule).
1801asserting_goal(assertz(Rule,_), Rule).
1802
1803process_assert(0, _, _) :- !. 1804process_assert((_:-Body), Origin, Src) :-
1805 !,
1806 process_body(Body, Origin, Src).
1807process_assert(_, _, _).
1808
1810
1811variants([], _, []).
1812variants([H|T], Max, List) :-
1813 variants(T, H, Max, List).
1814
1815variants([], H, _, [H]).
1816variants(_, _, 0, []) :- !.
1817variants([H|T], V, Max, List) :-
1818 ( H =@= V
1819 -> variants(T, V, Max, List)
1820 ; List = [V|List2],
1821 Max1 is Max-1,
1822 variants(T, H, Max1, List2)
1823 ).
1824
1836
1837partial_evaluate(Goal, P) :-
1838 eval(Goal),
1839 !,
1840 P = true.
1841partial_evaluate(_, _).
1842
1843eval(X = Y) :-
1844 unify_with_occurs_check(X, Y).
1845
1846 1849
1850enter_test_unit(Unit, _Src) :-
1851 current_source_line(Line),
1852 asserta(current_test_unit(Unit, Line)).
1853
1854leave_test_unit(Unit, _Src) :-
1855 retractall(current_test_unit(Unit, _)).
1856
1857
1858 1861
1862pce_goal(new(_,_), new(-, new)).
1863pce_goal(send(_,_), send(arg, msg)).
1864pce_goal(send_class(_,_,_), send_class(arg, arg, msg)).
1865pce_goal(get(_,_,_), get(arg, msg, -)).
1866pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)).
1867pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)).
1868pce_goal(get_object(_,_,_), get_object(arg, msg, -)).
1869
1870process_xpce_goal(G, Origin, Src) :-
1871 pce_goal(G, Process),
1872 !,
1873 current_source_line(Here),
1874 assert_called(Src, Origin, G, Here),
1875 ( arg(I, Process, How),
1876 arg(I, G, Term),
1877 process_xpce_arg(How, Term, Origin, Src),
1878 fail
1879 ; true
1880 ).
1881
1882process_xpce_arg(new, Term, Origin, Src) :-
1883 callable(Term),
1884 process_new(Term, Origin, Src).
1885process_xpce_arg(arg, Term, Origin, Src) :-
1886 compound(Term),
1887 process_new(Term, Origin, Src).
1888process_xpce_arg(msg, Term, Origin, Src) :-
1889 compound(Term),
1890 ( arg(_, Term, Arg),
1891 process_xpce_arg(arg, Arg, Origin, Src),
1892 fail
1893 ; true
1894 ).
1895
1896process_new(_M:_Term, _, _) :- !. 1897process_new(Term, Origin, Src) :-
1898 assert_new(Src, Origin, Term),
1899 ( compound(Term),
1900 arg(_, Term, Arg),
1901 process_xpce_arg(arg, Arg, Origin, Src),
1902 fail
1903 ; true
1904 ).
1905
1906assert_new(_, _, Term) :-
1907 \+ callable(Term),
1908 !.
1909assert_new(Src, Origin, Control) :-
1910 functor_name(Control, Class),
1911 pce_control_class(Class),
1912 !,
1913 forall(arg(_, Control, Arg),
1914 assert_new(Src, Origin, Arg)).
1915assert_new(Src, Origin, Term) :-
1916 compound(Term),
1917 arg(1, Term, Prolog),
1918 Prolog == @(prolog),
1919 ( Term =.. [message, _, Selector | T],
1920 atom(Selector)
1921 -> Called =.. [Selector|T],
1922 process_body(Called, Origin, Src)
1923 ; Term =.. [?, _, Selector | T],
1924 atom(Selector)
1925 -> append(T, [_R], T2),
1926 Called =.. [Selector|T2],
1927 process_body(Called, Origin, Src)
1928 ),
1929 fail.
1930assert_new(_, _, @(_)) :- !.
1931assert_new(Src, _, Term) :-
1932 functor_name(Term, Name),
1933 assert_used_class(Src, Name).
1934
1935
1936pce_control_class(and).
1937pce_control_class(or).
1938pce_control_class(if).
1939pce_control_class(not).
1940
1941
1942 1945
1947
1948process_use_module(_Module:_Files, _, _) :- !. 1949process_use_module([], _, _) :- !.
1950process_use_module([H|T], Src, Reexport) :-
1951 !,
1952 process_use_module(H, Src, Reexport),
1953 process_use_module(T, Src, Reexport).
1954process_use_module(library(pce), Src, Reexport) :- 1955 !,
1956 xref_public_list(library(pce), Path, Exports, Src),
1957 forall(member(Import, Exports),
1958 process_pce_import(Import, Src, Path, Reexport)).
1959process_use_module(File, Src, Reexport) :-
1960 load_module_if_needed(File),
1961 ( xoption(Src, silent(Silent))
1962 -> Extra = [silent(Silent)]
1963 ; Extra = [silent(true)]
1964 ),
1965 ( xref_public_list(File, Src,
1966 [ path(Path),
1967 module(M),
1968 exports(Exports),
1969 public(Public),
1970 meta(Meta)
1971 | Extra
1972 ])
1973 -> assert(uses_file(File, Src, Path)),
1974 assert_import(Src, Exports, _, Path, Reexport),
1975 assert_xmodule_callable(Exports, M, Src, Path),
1976 assert_xmodule_callable(Public, M, Src, Path),
1977 maplist(process_meta_head(Src), Meta),
1978 ( File = library(chr) 1979 -> assert(mode(chr, Src))
1980 ; true
1981 )
1982 ; assert(uses_file(File, Src, '<not_found>'))
1983 ).
1984
1985process_pce_import(Name/Arity, Src, Path, Reexport) :-
1986 atom(Name),
1987 integer(Arity),
1988 !,
1989 functor(Term, Name, Arity),
1990 ( \+ system_predicate(Term),
1991 \+ Term = pce_error(_) 1992 -> assert_import(Src, [Name/Arity], _, Path, Reexport)
1993 ; true
1994 ).
1995process_pce_import(op(P,T,N), Src, _, _) :-
1996 xref_push_op(Src, P, T, N).
1997
2001
2002process_use_module2(File, Import, Src, Reexport) :-
2003 load_module_if_needed(File),
2004 ( catch(xref_public_list(File, Src,
2005 [ path(Path),
2006 exports(Export),
2007 meta(Meta)
2008 ]),
2009 error(_,_),
2010 fail)
2011 -> assertz(uses_file(File, Src, Path)),
2012 assert_import(Src, Import, Export, Path, Reexport),
2013 forall(( member(Head, Meta),
2014 imported(Head, _, Path)
2015 ),
2016 process_meta_head(Src, Head))
2017 ; assertz(uses_file(File, Src, '<not_found>'))
2018 ).
2019
2020
2026
2027load_module_if_needed(File) :-
2028 prolog:no_autoload_module(File),
2029 !,
2030 use_module(File, []).
2031load_module_if_needed(_).
2032
2033prolog:no_autoload_module(library(apply_macros)).
2034prolog:no_autoload_module(library(arithmetic)).
2035prolog:no_autoload_module(library(record)).
2036prolog:no_autoload_module(library(persistency)).
2037prolog:no_autoload_module(library(pldoc)).
2038prolog:no_autoload_module(library(settings)).
2039prolog:no_autoload_module(library(debug)).
2040prolog:no_autoload_module(library(plunit)).
2041prolog:no_autoload_module(library(macros)).
2042prolog:no_autoload_module(library(yall)).
2043
2044
2046
2047process_requires(Import, Src) :-
2048 is_list(Import),
2049 !,
2050 require_list(Import, Src).
2051process_requires(Var, _Src) :-
2052 var(Var),
2053 !.
2054process_requires((A,B), Src) :-
2055 !,
2056 process_requires(A, Src),
2057 process_requires(B, Src).
2058process_requires(PI, Src) :-
2059 requires(PI, Src).
2060
2061require_list([], _).
2062require_list([H|T], Src) :-
2063 requires(H, Src),
2064 require_list(T, Src).
2065
2066requires(PI, _Src) :-
2067 '$pi_head'(PI, Head),
2068 '$get_predicate_attribute'(system:Head, defined, 1),
2069 !.
2070requires(PI, Src) :-
2071 '$pi_head'(PI, Head),
2072 '$pi_head'(Name/Arity, Head),
2073 '$find_library'(_Module, Name, Arity, _LoadModule, Library),
2074 ( imported(Head, Src, Library)
2075 -> true
2076 ; assertz(imported(Head, Src, Library))
2077 ).
2078
2079
2112
2113xref_public_list(File, Src, Options) :-
2114 option(path(Source), Options, _),
2115 option(module(Module), Options, _),
2116 option(exports(Exports), Options, _),
2117 option(public(Public), Options, _),
2118 option(meta(Meta), Options, _),
2119 xref_source_file(File, Path, Src, Options),
2120 public_list(Path, Source, Module, Meta, Exports, Public, Options).
2121
2143
2144xref_public_list(File, Source, Export, Src) :-
2145 xref_source_file(File, Path, Src),
2146 public_list(Path, Source, _, _, Export, _, []).
2147xref_public_list(File, Source, Module, Export, Meta, Src) :-
2148 xref_source_file(File, Path, Src),
2149 public_list(Path, Source, Module, Meta, Export, _, []).
2150xref_public_list(File, Source, Module, Export, Public, Meta, Src) :-
2151 xref_source_file(File, Path, Src),
2152 public_list(Path, Source, Module, Meta, Export, Public, []).
2153
2162
2163:- dynamic public_list_cache/7. 2164:- volatile public_list_cache/7. 2165
2166public_list(Path, Source, Module, Meta, Export, Public, _Options) :-
2167 \+ is_stream(Path),
2168 public_list_cache(Path, Source, Modified,
2169 Module0, Meta0, Export0, Public0),
2170 time_file(Path, ModifiedNow),
2171 ( abs(Modified-ModifiedNow) < 0.0001
2172 -> !,
2173 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0)
2174 ; retractall(public_list_cache(Path, _, _, _, _, _, _)),
2175 fail
2176 ).
2177public_list(Path, Source, Module, Meta, Export, Public, Options) :-
2178 public_list_nc(Path, Source, Module0, Meta0, Export0, Public0, Options),
2179 ( Error = error(_,_),
2180 catch(time_file(Path, Modified), Error, fail)
2181 -> asserta(public_list_cache(Path, Source, Modified,
2182 Module0, Meta0, Export0, Public0))
2183 ; true
2184 ),
2185 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0).
2186
2187public_list_nc(Path, Source, Module, Meta, Export, Public, _Options) :-
2188 \+ is_stream(Path),
2189 public_list_from_index(Path, Module, Meta, Export, Public),
2190 !,
2191 qlf_pl_file(Path, Source).
2192public_list_nc(Path, Source, Module, [], Export, [], _Options) :-
2193 \+ is_stream(Path),
2194 is_qlf_file(Path),
2195 !,
2196 '$qlf_module'(Path, Info),
2197 _{module:Module, exports:Export, file:Source} :< Info.
2198public_list_nc(Path, Path, Module, Meta, Export, Public, Options) :-
2199 ( is_stream(Path)
2200 ; exists_file(Path)
2201 ),
2202 !,
2203 prolog_file_directives(Path, Directives, Options),
2204 public_list(Directives, Path, Module, Meta, [], Export, [], Public, []).
2205public_list_nc(Path, Path, Module, [], Export, [], _Options) :-
2206 \+ is_stream(Path),
2207 qlf_pl_file(QlfFile, Path),
2208 '$qlf_module'(QlfFile, Info),
2209 _{module:Module, exports:Export} :< Info.
2210
2211public_list([(:- module(Module, Export0))|Decls], Path,
2212 Module, Meta, MT, Export, Rest, Public, PT) :-
2213 !,
2214 ( is_list(Export0)
2215 -> append(Export0, Reexport, Export)
2216 ; Reexport = Export
2217 ),
2218 public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT).
2219public_list([(:- encoding(_))|Decls], Path,
2220 Module, Meta, MT, Export, Rest, Public, PT) :-
2221 public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT).
2222
2223public_list_([], _, Meta, Meta, Export, Export, Public, Public).
2224public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :-
2225 public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0),
2226 !,
2227 public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT).
2228public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :-
2229 public_list_(T, Path, Meta, MT, Export, Rest, Public, PT).
2230
2231public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :-
2232 reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT).
2233public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :-
2234 public_from_import(Import, Spec, Path, Reexport, Rest).
2235public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :-
2236 phrase(meta_decls(Decl), Meta, MT).
2237public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :-
2238 phrase(public_decls(Decl), Public, PT).
2239
2243
2244reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !.
2245reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :-
2246 !,
2247 xref_source_file(H, Path, Src),
2248 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []),
2249 append(Meta0, MT1, Meta),
2250 append(Export0, ET1, Export),
2251 append(Public0, PT1, Public),
2252 reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT).
2253reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :-
2254 xref_source_file(Spec, Path, Src),
2255 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []),
2256 append(Meta0, MT, Meta),
2257 append(Export0, ET, Export),
2258 append(Public0, PT, Public).
2259
2260public_from_import(except(Map), Path, Src, Export, Rest) :-
2261 !,
2262 xref_public_list(Path, _, AllExports, Src),
2263 except(Map, AllExports, NewExports),
2264 append(NewExports, Rest, Export).
2265public_from_import(Import, _, _, Export, Rest) :-
2266 import_name_map(Import, Export, Rest).
2267
2268
2270
2271except([], Exports, Exports).
2272except([PI0 as NewName|Map], Exports0, Exports) :-
2273 !,
2274 canonical_pi(PI0, PI),
2275 map_as(Exports0, PI, NewName, Exports1),
2276 except(Map, Exports1, Exports).
2277except([PI0|Map], Exports0, Exports) :-
2278 canonical_pi(PI0, PI),
2279 select(PI2, Exports0, Exports1),
2280 same_pi(PI, PI2),
2281 !,
2282 except(Map, Exports1, Exports).
2283
2284
2285map_as([PI|T], Repl, As, [PI2|T]) :-
2286 same_pi(Repl, PI),
2287 !,
2288 pi_as(PI, As, PI2).
2289map_as([H|T0], Repl, As, [H|T]) :-
2290 map_as(T0, Repl, As, T).
2291
2292pi_as(_/Arity, Name, Name/Arity).
2293pi_as(_//Arity, Name, Name//Arity).
2294
2295import_name_map([], L, L).
2296import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :-
2297 !,
2298 import_name_map(T0, T, Tail).
2299import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :-
2300 !,
2301 import_name_map(T0, T, Tail).
2302import_name_map([H|T0], [H|T], Tail) :-
2303 import_name_map(T0, T, Tail).
2304
2305canonical_pi(Name//Arity0, PI) :-
2306 integer(Arity0),
2307 !,
2308 PI = Name/Arity,
2309 Arity is Arity0 + 2.
2310canonical_pi(PI, PI).
2311
2312same_pi(Canonical, PI2) :-
2313 canonical_pi(PI2, Canonical).
2314
2315meta_decls(Var) -->
2316 { var(Var) },
2317 !.
2318meta_decls((A,B)) -->
2319 !,
2320 meta_decls(A),
2321 meta_decls(B).
2322meta_decls(A) -->
2323 [A].
2324
2325public_decls(Var) -->
2326 { var(Var) },
2327 !.
2328public_decls((A,B)) -->
2329 !,
2330 public_decls(A),
2331 public_decls(B).
2332public_decls(A) -->
2333 [A].
2334
2339
2340public_list_from_index(Path, Module, Meta, Export, Public) :-
2341 file_name_extension(BasePath, _Ext, Path),
2342 file_directory_name(BasePath, Dir),
2343 atom_concat(Dir, '/INDEX.pl', IndexFile),
2344 exists_file(IndexFile),
2345 file_base_name(BasePath, Base),
2346 setup_call_cleanup(
2347 '$push_input_context'(autoload_index),
2348 setup_call_cleanup(
2349 open(IndexFile, read, In),
2350 index_public_list(In, Base, Module, Meta, Export, Public),
2351 close(In)),
2352 '$pop_input_context').
2353
2354index_public_list(In, Base, Module, Meta, Export, Public) :-
2355 read_term(In, Term, []),
2356 index_public_list(Term, In, Base, Module, Meta, Export, Public).
2357
2358index_public_list(end_of_file, _In, _Base, _Module, [], [], []).
2359index_public_list(index(op:Op, Module, Base), In, Base, Module, Meta, [Op|Export], Public) :-
2360 !,
2361 read_term(In, Term, []),
2362 index_public_list(Term, In, Base, Module, Meta, Export, Public).
2363index_public_list(index((public):Head, Module, Base), In, Base, Module, Meta, Export, [PI|Public]) :-
2364 !,
2365 pi_head(PI, Head),
2366 read_term(In, Term, []),
2367 index_public_list(Term, In, Base, Module, Meta, Export, Public).
2368index_public_list(index(Head, Module, Base), In, Base, Module, Meta, [PI|Export], Public) :-
2369 !,
2370 pi_head(PI, Head),
2371 ( meta_mode(Head)
2372 -> Meta = [Head|MetaT]
2373 ; Meta = MetaT
2374 ),
2375 read_term(In, Term, []),
2376 index_public_list(Term, In, Base, Module, MetaT, Export, Public).
2377index_public_list(index(Name, Arity, Module, Base), In, Base, Module, Meta, [Name/Arity|Export], Public) :-
2378 !,
2379 read_term(In, Term, []),
2380 index_public_list(Term, In, Base, Module, Meta, Export, Public).
2381index_public_list(_, In, Base, Module, Meta, Export, Public) :-
2382 read_term(In, Term, []),
2383 index_public_list(Term, In, Base, Module, Meta, Export, Public).
2384
2385meta_mode(H) :-
2386 compound(H),
2387 arg(_, H, A),
2388 meta_arg(A),
2389 !.
2390
2391meta_arg(I) :-
2392 integer(I),
2393 !.
2394meta_arg(:).
2395meta_arg(^).
2396meta_arg(//).
2397
2398 2401
2402process_include([], _) :- !.
2403process_include([H|T], Src) :-
2404 !,
2405 process_include(H, Src),
2406 process_include(T, Src).
2407process_include(File, Src) :-
2408 callable(File),
2409 !,
2410 ( once(xref_input(ParentSrc, _)),
2411 xref_source_file(File, Path, ParentSrc)
2412 -> ( ( uses_file(_, Src, Path)
2413 ; Path == Src
2414 )
2415 -> true
2416 ; assert(uses_file(File, Src, Path)),
2417 ( xoption(Src, process_include(true))
2418 -> findall(O, xoption(Src, O), Options),
2419 setup_call_cleanup(
2420 open_include_file(Path, In, Refs),
2421 collect(Src, Path, In, Options),
2422 close_include(In, Refs))
2423 ; true
2424 )
2425 )
2426 ; assert(uses_file(File, Src, '<not_found>'))
2427 ).
2428process_include(_, _).
2429
2435
2436open_include_file(Path, In, [Ref]) :-
2437 once(xref_input(_, Parent)),
2438 stream_property(Parent, encoding(Enc)),
2439 '$push_input_context'(xref_include),
2440 catch(( prolog:xref_open_source(Path, In)
2441 -> catch(set_stream(In, encoding(Enc)),
2442 error(_,_), true) 2443 ; include_encoding(Enc, Options),
2444 open(Path, read, In, Options)
2445 ), E,
2446 ( '$pop_input_context', throw(E))),
2447 catch(( peek_char(In, #) 2448 -> skip(In, 10)
2449 ; true
2450 ), E,
2451 ( close_include(In, []), throw(E))),
2452 asserta(xref_input(Path, In), Ref).
2453
2454include_encoding(wchar_t, []) :- !.
2455include_encoding(Enc, [encoding(Enc)]).
2456
2457
2458close_include(In, Refs) :-
2459 maplist(erase, Refs),
2460 close(In, [force(true)]),
2461 '$pop_input_context'.
2462
2466
2467process_foreign(Spec, Src) :-
2468 ground(Spec),
2469 current_foreign_library(Spec, Defined),
2470 !,
2471 ( xmodule(Module, Src)
2472 -> true
2473 ; Module = user
2474 ),
2475 process_foreign_defined(Defined, Module, Src).
2476process_foreign(_, _).
2477
2478process_foreign_defined([], _, _).
2479process_foreign_defined([H|T], M, Src) :-
2480 ( H = M:Head
2481 -> assert_foreign(Src, Head)
2482 ; assert_foreign(Src, H)
2483 ),
2484 process_foreign_defined(T, M, Src).
2485
2486
2487 2490
2500
2501process_chr(@(_Name, Rule), Src) :-
2502 mode(chr, Src),
2503 process_chr(Rule, Src).
2504process_chr(pragma(Rule, _Pragma), Src) :-
2505 mode(chr, Src),
2506 process_chr(Rule, Src).
2507process_chr(<=>(Head, Body), Src) :-
2508 mode(chr, Src),
2509 chr_head(Head, Src, H),
2510 chr_body(Body, H, Src).
2511process_chr(==>(Head, Body), Src) :-
2512 mode(chr, Src),
2513 chr_head(Head, H, Src),
2514 chr_body(Body, H, Src).
2515process_chr((:- chr_constraint(Decls)), Src) :-
2516 ( mode(chr, Src)
2517 -> true
2518 ; assert(mode(chr, Src))
2519 ),
2520 chr_decls(Decls, Src).
2521
2522chr_decls((A,B), Src) =>
2523 chr_decls(A, Src),
2524 chr_decls(B, Src).
2525chr_decls(Head, Src) =>
2526 generalise_term(Head, Gen),
2527 ( declared(Gen, chr_constraint, Src, _)
2528 -> true
2529 ; current_source_line(Line),
2530 assertz(declared(Gen, chr_constraint, Src, Line))
2531 ).
2532
2533chr_head(X, _, _) :-
2534 var(X),
2535 !. 2536chr_head(\(A,B), Src, H) :-
2537 chr_head(A, Src, H),
2538 process_body(B, H, Src).
2539chr_head((H0,B), Src, H) :-
2540 chr_defined(H0, Src, H),
2541 process_body(B, H, Src).
2542chr_head(H0, Src, H) :-
2543 chr_defined(H0, Src, H).
2544
2545chr_defined(X, _, _) :-
2546 var(X),
2547 !.
2548chr_defined(#(C,_Id), Src, C) :-
2549 !,
2550 assert_constraint(Src, C).
2551chr_defined(A, Src, A) :-
2552 assert_constraint(Src, A).
2553
2554chr_body(X, From, Src) :-
2555 var(X),
2556 !,
2557 process_body(X, From, Src).
2558chr_body('|'(Guard, Goals), H, Src) :-
2559 !,
2560 chr_body(Guard, H, Src),
2561 chr_body(Goals, H, Src).
2562chr_body(G, From, Src) :-
2563 process_body(G, From, Src).
2564
2565assert_constraint(_, Head) :-
2566 var(Head),
2567 !.
2568assert_constraint(Src, Head) :-
2569 constraint(Head, Src, _),
2570 !.
2571assert_constraint(Src, Head) :-
2572 generalise_term(Head, Term),
2573 current_source_line(Line),
2574 assert(constraint(Term, Src, Line)).
2575
2576
2577 2580
2585
2586assert_called(_, _, Var, _) :-
2587 var(Var),
2588 !.
2589assert_called(Src, From, Goal, Line) :-
2590 var(From),
2591 !,
2592 assert_called(Src, '<unknown>', Goal, Line).
2593assert_called(_, _, Goal, _) :-
2594 expand_hide_called(Goal),
2595 !.
2596assert_called(Src, Origin, M:G, Line) :-
2597 !,
2598 ( atom(M),
2599 callable(G)
2600 -> current_condition(Cond),
2601 ( xmodule(M, Src) 2602 -> assert_called(Src, Origin, G, Line)
2603 ; called(M:G, Src, Origin, Cond, Line) 2604 -> true
2605 ; hide_called(M:G, Src) 2606 -> true
2607 ; generalise(Origin, OTerm),
2608 generalise(G, GTerm)
2609 -> assert(called(M:GTerm, Src, OTerm, Cond, Line))
2610 ; true
2611 )
2612 ; true 2613 ).
2614assert_called(Src, _, Goal, _) :-
2615 ( xmodule(M, Src)
2616 -> M \== system
2617 ; M = user
2618 ),
2619 hide_called(M:Goal, Src),
2620 !.
2621assert_called(Src, Origin, Goal, Line) :-
2622 current_condition(Cond),
2623 ( called(Goal, Src, Origin, Cond, Line)
2624 -> true
2625 ; generalise(Origin, OTerm),
2626 generalise(Goal, Term)
2627 -> assert(called(Term, Src, OTerm, Cond, Line))
2628 ; true
2629 ).
2630
2631
2636
2637expand_hide_called(pce_principal:send_implementation(_, _, _)).
2638expand_hide_called(pce_principal:get_implementation(_, _, _, _)).
2639expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)).
2640expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)).
2641
2642assert_defined(Src, Goal) :-
2643 Goal = test(_Test),
2644 current_test_unit(Unit, Line),
2645 assert_called(Src, '<test_unit>'(Unit), Goal, Line),
2646 fail.
2647assert_defined(Src, Goal) :-
2648 Goal = test(_Test, _Options),
2649 current_test_unit(Unit, Line),
2650 assert_called(Src, '<test_unit>'(Unit), Goal, Line),
2651 fail.
2652assert_defined(Src, Goal) :-
2653 defined(Goal, Src, _),
2654 !.
2655assert_defined(Src, Goal) :-
2656 generalise(Goal, Term),
2657 current_source_line(Line),
2658 assert(defined(Term, Src, Line)).
2659
2660assert_foreign(Src, Goal) :-
2661 foreign(Goal, Src, _),
2662 !.
2663assert_foreign(Src, Goal) :-
2664 generalise(Goal, Term),
2665 current_source_line(Line),
2666 assert(foreign(Term, Src, Line)).
2667
2668assert_grammar_rule(Src, Goal) :-
2669 grammar_rule(Goal, Src),
2670 !.
2671assert_grammar_rule(Src, Goal) :-
2672 generalise(Goal, Term),
2673 assert(grammar_rule(Term, Src)).
2674
2675
2685
2686assert_import(_, [], _, _, _) :- !.
2687assert_import(Src, [H|T], Export, From, Reexport) :-
2688 !,
2689 assert_import(Src, H, Export, From, Reexport),
2690 assert_import(Src, T, Export, From, Reexport).
2691assert_import(Src, except(Except), Export, From, Reexport) :-
2692 !,
2693 is_list(Export),
2694 !,
2695 except(Except, Export, Import),
2696 assert_import(Src, Import, _All, From, Reexport).
2697assert_import(Src, Import as Name, Export, From, Reexport) :-
2698 !,
2699 pi_to_head(Import, Term0),
2700 rename_goal(Term0, Name, Term),
2701 ( in_export_list(Term0, Export)
2702 -> assert(imported(Term, Src, From)),
2703 assert_reexport(Reexport, Src, Term)
2704 ; current_source_line(Line),
2705 assert_called(Src, '<directive>'(Line), Term0, Line)
2706 ).
2707assert_import(Src, Import, Export, From, Reexport) :-
2708 pi_to_head(Import, Term),
2709 !,
2710 ( in_export_list(Term, Export)
2711 -> assert(imported(Term, Src, From)),
2712 assert_reexport(Reexport, Src, Term)
2713 ; current_source_line(Line),
2714 assert_called(Src, '<directive>'(Line), Term, Line)
2715 ).
2716assert_import(Src, op(P,T,N), _, _, _) :-
2717 xref_push_op(Src, P,T,N).
2718
2719in_export_list(_Head, Export) :-
2720 var(Export),
2721 !.
2722in_export_list(Head, Export) :-
2723 member(PI, Export),
2724 pi_to_head(PI, Head).
2725
2726assert_reexport(false, _, _) :- !.
2727assert_reexport(true, Src, Term) :-
2728 assert(exported(Term, Src)).
2729
2733
2734process_import(M:PI, Src) :-
2735 pi_to_head(PI, Head),
2736 !,
2737 ( atom(M),
2738 current_module(M),
2739 module_property(M, file(From))
2740 -> true
2741 ; From = '<unknown>'
2742 ),
2743 assert(imported(Head, Src, From)).
2744process_import(_, _).
2745
2752
2753assert_xmodule_callable([], _, _, _).
2754assert_xmodule_callable([PI|T], M, Src, From) :-
2755 ( pi_to_head(M:PI, Head)
2756 -> assert(imported(Head, Src, From))
2757 ; true
2758 ),
2759 assert_xmodule_callable(T, M, Src, From).
2760
2761
2765
2766assert_op(Src, op(P,T,M:N)) :-
2767 ( '$current_source_module'(M)
2768 -> Name = N
2769 ; Name = M:N
2770 ),
2771 ( xop(Src, op(P,T,Name))
2772 -> true
2773 ; assert(xop(Src, op(P,T,Name)))
2774 ).
2775
2780
2781assert_module(Src, Module) :-
2782 xmodule(Module, Src),
2783 !.
2784assert_module(Src, Module) :-
2785 '$set_source_module'(Module),
2786 assert(xmodule(Module, Src)),
2787 ( module_property(Module, class(system))
2788 -> retractall(xoption(Src, register_called(_))),
2789 assert(xoption(Src, register_called(all)))
2790 ; true
2791 ).
2792
2793assert_module_export(_, []) :- !.
2794assert_module_export(Src, [H|T]) :-
2795 !,
2796 assert_module_export(Src, H),
2797 assert_module_export(Src, T).
2798assert_module_export(Src, PI) :-
2799 pi_to_head(PI, Term),
2800 !,
2801 assert(exported(Term, Src)).
2802assert_module_export(Src, op(P, A, N)) :-
2803 xref_push_op(Src, P, A, N).
2804
2808
2809assert_module3([], _) :- !.
2810assert_module3([H|T], Src) :-
2811 !,
2812 assert_module3(H, Src),
2813 assert_module3(T, Src).
2814assert_module3(Option, Src) :-
2815 process_use_module(library(dialect/Option), Src, false).
2816
2817
2823
2824process_predicates(Closure, Preds, Src) :-
2825 is_list(Preds),
2826 !,
2827 process_predicate_list(Preds, Closure, Src).
2828process_predicates(Closure, as(Preds, _Options), Src) :-
2829 !,
2830 process_predicates(Closure, Preds, Src).
2831process_predicates(Closure, Preds, Src) :-
2832 process_predicate_comma(Preds, Closure, Src).
2833
2834process_predicate_list([], _, _).
2835process_predicate_list([H|T], Closure, Src) :-
2836 ( nonvar(H)
2837 -> call(Closure, H, Src)
2838 ; true
2839 ),
2840 process_predicate_list(T, Closure, Src).
2841
2842process_predicate_comma(Var, _, _) :-
2843 var(Var),
2844 !.
2845process_predicate_comma(M:(A,B), Closure, Src) :-
2846 !,
2847 process_predicate_comma(M:A, Closure, Src),
2848 process_predicate_comma(M:B, Closure, Src).
2849process_predicate_comma((A,B), Closure, Src) :-
2850 !,
2851 process_predicate_comma(A, Closure, Src),
2852 process_predicate_comma(B, Closure, Src).
2853process_predicate_comma(as(Spec, _Options), Closure, Src) :-
2854 !,
2855 process_predicate_comma(Spec, Closure, Src).
2856process_predicate_comma(A, Closure, Src) :-
2857 call(Closure, A, Src).
2858
2859
2860assert_dynamic(PI, Src) :-
2861 pi_to_head(PI, Term),
2862 ( thread_local(Term, Src, _) 2863 -> true 2864 ; current_source_line(Line),
2865 assert(dynamic(Term, Src, Line))
2866 ).
2867
2868assert_thread_local(PI, Src) :-
2869 pi_to_head(PI, Term),
2870 current_source_line(Line),
2871 assert(thread_local(Term, Src, Line)).
2872
2873assert_multifile(PI, Src) :- 2874 pi_to_head(PI, Term),
2875 current_source_line(Line),
2876 assert(multifile(Term, Src, Line)).
2877
2878assert_public(PI, Src) :- 2879 pi_to_head(PI, Term),
2880 current_source_line(Line),
2881 assert_called(Src, '<public>'(Line), Term, Line),
2882 assert(public(Term, Src, Line)).
2883
2884assert_export(PI, Src) :- 2885 pi_to_head(PI, Term),
2886 !,
2887 assert(exported(Term, Src)).
2888
2893
2894pi_to_head(Var, _) :-
2895 var(Var), !, fail.
2896pi_to_head(M:PI, M:Term) :-
2897 !,
2898 pi_to_head(PI, Term).
2899pi_to_head(Name/Arity, Term) :-
2900 functor(Term, Name, Arity).
2901pi_to_head(Name//DCGArity, Term) :-
2902 Arity is DCGArity+2,
2903 functor(Term, Name, Arity).
2904
2905
2906assert_used_class(Src, Name) :-
2907 used_class(Name, Src),
2908 !.
2909assert_used_class(Src, Name) :-
2910 assert(used_class(Name, Src)).
2911
2912assert_defined_class(Src, Name, _Meta, _Super, _) :-
2913 defined_class(Name, _, _, Src, _),
2914 !.
2915assert_defined_class(_, _, _, -, _) :- !. 2916assert_defined_class(Src, Name, Meta, Super, Summary) :-
2917 current_source_line(Line),
2918 ( Summary == @(default)
2919 -> Atom = ''
2920 ; is_list(Summary)
2921 -> atom_codes(Atom, Summary)
2922 ; string(Summary)
2923 -> atom_concat(Summary, '', Atom)
2924 ),
2925 assert(defined_class(Name, Super, Atom, Src, Line)),
2926 ( Meta = @(_)
2927 -> true
2928 ; assert_used_class(Src, Meta)
2929 ),
2930 assert_used_class(Src, Super).
2931
2932assert_defined_class(Src, Name, imported_from(_File)) :-
2933 defined_class(Name, _, _, Src, _),
2934 !.
2935assert_defined_class(Src, Name, imported_from(File)) :-
2936 assert(defined_class(Name, _, '', Src, file(File))).
2937
2938
2939 2942
2946
2947generalise(Var, Var) :-
2948 var(Var),
2949 !. 2950generalise(pce_principal:send_implementation(Id, _, _),
2951 pce_principal:send_implementation(Id, _, _)) :-
2952 atom(Id),
2953 !.
2954generalise(pce_principal:get_implementation(Id, _, _, _),
2955 pce_principal:get_implementation(Id, _, _, _)) :-
2956 atom(Id),
2957 !.
2958generalise('<directive>'(Line), '<directive>'(Line)) :- !.
2959generalise(test(Test), test(Test)) :-
2960 current_test_unit(_,_),
2961 ground(Test),
2962 !.
2963generalise(test(Test, _), test(Test, _)) :-
2964 current_test_unit(_,_),
2965 ground(Test),
2966 !.
2967generalise('<test_unit>'(Line), '<test_unit>'(Line)) :- !.
2968generalise(Module:Goal0, Module:Goal) :-
2969 atom(Module),
2970 !,
2971 generalise(Goal0, Goal).
2972generalise(Term0, Term) :-
2973 callable(Term0),
2974 generalise_term(Term0, Term).
2975
2976
2977 2980
2988
2989:- multifile
2990 prolog:xref_source_directory/2, 2991 prolog:xref_source_file/3. 2992
2993
2998
2999xref_source_file(Plain, File, Source) :-
3000 xref_source_file(Plain, File, Source, []).
3001
3002xref_source_file(QSpec, File, Source, Options) :-
3003 nonvar(QSpec), QSpec = _:Spec,
3004 !,
3005 must_be(acyclic, Spec),
3006 xref_source_file(Spec, File, Source, Options).
3007xref_source_file(Spec, File, _Source, _Options) :-
3008 is_stream(Spec), !,
3009 File = Spec.
3010xref_source_file(Spec, File, Source, Options) :-
3011 nonvar(Spec),
3012 prolog:xref_source_file(Spec, File,
3013 [ relative_to(Source)
3014 | Options
3015 ]),
3016 !.
3017xref_source_file(Plain, File, Source, Options) :-
3018 atom(Plain),
3019 \+ is_absolute_file_name(Plain),
3020 ( prolog:xref_source_directory(Source, Dir)
3021 -> true
3022 ; atom(Source),
3023 file_directory_name(Source, Dir)
3024 ),
3025 atomic_list_concat([Dir, /, Plain], Spec0),
3026 absolute_file_name(Spec0, Spec),
3027 do_xref_source_file(Spec, File, Options),
3028 !.
3029xref_source_file(Spec, File, Source, Options) :-
3030 do_xref_source_file(Spec, File,
3031 [ relative_to(Source)
3032 | Options
3033 ]),
3034 !.
3035xref_source_file(_, _, _, Options) :-
3036 option(silent(true), Options),
3037 !,
3038 fail.
3039xref_source_file(Spec, _, Src, _Options) :-
3040 verbose(Src),
3041 print_message(warning, error(existence_error(file, Spec), _)),
3042 fail.
3043
3044do_xref_source_file(Spec, File, Options) :-
3045 nonvar(Spec),
3046 option(file_type(Type), Options, prolog),
3047 absolute_file_name(Spec, File0,
3048 [ file_type(Type),
3049 access(read),
3050 file_errors(fail)
3051 ]),
3052 !,
3053 qlf_pl_file(File0, File).
3054do_xref_source_file(Spec, File, Options) :-
3055 atom(Spec), 3056 file_name_extension(Base, Ext, Spec),
3057 user:prolog_file_type(Ext, source),
3058 option(file_type(prolog), Options, prolog),
3059 absolute_file_name(Base, File0,
3060 [ file_type(prolog),
3061 access(read),
3062 file_errors(fail)
3063 ]),
3064 qlf_pl_file(File0, File).
3065
3067
3068qlf_pl_file(QlfFile, PlFile) :-
3069 nonvar(QlfFile),
3070 is_qlf_file(QlfFile),
3071 !,
3072 '$qlf_module'(QlfFile, Info),
3073 #{file:PlFile} :< Info.
3074qlf_pl_file(QlfFile, PlFile) :-
3075 nonvar(PlFile),
3076 !,
3077 ( file_name_extension(Base, Ext, PlFile),
3078 user:prolog_file_type(Ext, source)
3079 -> true
3080 ),
3081 ( user:prolog_file_type(QlfExt, qlf),
3082 file_name_extension(Base, QlfExt, QlfFile),
3083 exists_file(QlfFile)
3084 -> true
3085 ),
3086 '$qlf_module'(QlfFile, Info),
3087 #{file:PlFile} :< Info,
3088 !.
3089qlf_pl_file(PlFile, PlFile).
3090
3091is_qlf_file(QlfFile) :-
3092 file_name_extension(_, Ext, QlfFile),
3093 user:prolog_file_type(Ext, qlf),
3094 !.
3095
3099
3100canonical_source(Source, Src) :-
3101 ( ground(Source)
3102 -> prolog_canonical_source(Source, Src)
3103 ; Source = Src
3104 ).
3105
3110
3111goal_name_arity(Goal, Name, Arity) :-
3112 ( compound(Goal)
3113 -> compound_name_arity(Goal, Name, Arity)
3114 ; atom(Goal)
3115 -> Name = Goal, Arity = 0
3116 ).
3117
3118generalise_term(Specific, General) :-
3119 ( compound(Specific)
3120 -> compound_name_arity(Specific, Name, Arity),
3121 compound_name_arity(General, Name, Arity)
3122 ; General = Specific
3123 ).
3124
3125functor_name(Term, Name) :-
3126 ( compound(Term)
3127 -> compound_name_arity(Term, Name, _)
3128 ; atom(Term)
3129 -> Name = Term
3130 ).
3131
3132rename_goal(Goal0, Name, Goal) :-
3133 ( compound(Goal0)
3134 -> compound_name_arity(Goal0, _, Arity),
3135 compound_name_arity(Goal, Name, Arity)
3136 ; Goal = Name
3137 ).
3138
3139
3140
3143
3144:- multifile prolog:message//1.
3145
3146prolog:message(meta_predicate_after_call(Decl, By)) -->
3147 { pi_head(ByPI, By) },
3148 [ ansi(code, ':- meta_predicate(~p)', [Decl]),
3149 ' declaration appears after call from '-[],
3150 ansi(code, '~p', [ByPI])
3151 ]