1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: jan@swi-prolog.org 5 WWW: https://www.swi-prolog.org 6 Copyright (c) 2006-2026, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 SWI-Prolog Solutions b.v. 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 POSSIBILITY OF SUCH DAMAGE. 36*/ 37 38:- module(prolog_xref, 39 [ xref_source/1, % +Source 40 xref_source/2, % +Source, +Options 41 xref_called/3, % ?Source, ?Callable, ?By 42 xref_called/4, % ?Source, ?Callable, ?By, ?Cond 43 xref_called/5, % ?Source, ?Callable, ?By, ?Cond, ?Line 44 xref_defined/3, % ?Source. ?Callable, -How 45 xref_definition_line/2, % +How, -Line 46 xref_exported/2, % ?Source, ?Callable 47 xref_module/2, % ?Source, ?Module 48 xref_uses_file/3, % ?Source, ?Spec, ?Path 49 xref_op/2, % ?Source, ?Op 50 xref_prolog_flag/4, % ?Source, ?Flag, ?Value, ?Line 51 xref_comment/3, % ?Source, ?Title, ?Comment 52 xref_comment/4, % ?Source, ?Head, ?Summary, ?Comment 53 xref_object_comment/4, % ?Source, ?Object, ?Summary, ?Comment 54 xref_object_signature/3, % ?Source, ?Object, ?Signature 55 xref_mode/3, % ?Source, ?Mode, ?Det 56 xref_option/2, % ?Source, ?Option 57 xref_clean/1, % +Source 58 xref_current_source/1, % ?Source 59 xref_done/2, % +Source, -When 60 xref_built_in/1, % ?Callable 61 xref_source_file/3, % +Spec, -Path, +Source 62 xref_source_file/4, % +Spec, -Path, +Source, +Options 63 xref_public_list/3, % +File, +Src, +Options 64 xref_public_list/4, % +File, -Path, -Export, +Src 65 xref_public_list/6, % +File, -Path, -Module, -Export, -Meta, +Src 66 xref_public_list/7, % +File, -Path, -Module, -Export, -Public, -Meta, +Src 67 xref_meta/3, % +Source, +Goal, -Called 68 xref_meta/2, % +Goal, -Called 69 xref_hook/1, % ?Callable 70 % XPCE class references 71 xref_used_class/2, % ?Source, ?ClassName 72 xref_defined_class/3 % ?Source, ?ClassName, -How 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), []). % Must be loaded before doc_process 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, % Head, Src, From, Cond, Line 114 (dynamic)/3, % Head, Src, Line 115 (thread_local)/3, % Head, Src, Line 116 (multifile)/3, % Head, Src, Line 117 (public)/3, % Head, Src, Line 118 (declared)/4, % Head, How, Src, Line 119 defined/3, % Head, Src, Line 120 meta_goal/3, % Head, Called, Src 121 foreign/3, % Head, Src, Line 122 constraint/3, % Head, Src, Line 123 imported/3, % Head, Src, From 124 exported/2, % Head, Src 125 xmodule/2, % Module, Src 126 uses_file/3, % Spec, Src, Path 127 xop/2, % Src, Op 128 source/2, % Src, Time 129 used_class/2, % Name, Src 130 defined_class/5, % Name, Super, Summary, Src, Line 131 (mode)/2, % Mode, Src 132 xoption/2, % Src, Option 133 xflag/4, % Name, Value, Src, Line 134 grammar_rule/2, % Head, Src 135 module_comment/3, % Src, Title, Comment 136 pred_comment/4, % Head, Src, Summary, Comment 137 pred_comment_link/3, % Head, Src, HeadTo 138 pred_mode/3, % Head, Src, Det 139 object_comment/4, % Object, Src, Summary, Comment 140 object_signature/3. % Object, Src, Signature 141 142:- create_prolog_flag(xref, false, [type(boolean)]).
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 /******************************* 194 * HOOKS * 195 *******************************/
222:- multifile 223 prolog:called_by/4, % +Goal, +Module, +Context, -Called 224 prolog:called_by/2, % +Goal, -Called 225 prolog:meta_goal/2, % +Goal, -Pattern 226 prolog:hook/1, % +Callable 227 prolog:generated_predicate/1, % :PI 228 prolog:no_autoload_module/1, % Module is not suitable for autoloading. 229 prolog:xref_source_time/2. % +Source, =Modified 230 231:- meta_predicate 232 prolog:generated_predicate(). 233 234:- meta_predicate 235 process_predicates(, , ). 236 237 /******************************* 238 * BUILT-INS * 239 *******************************/
register_called.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).
272system_predicate(Goal) :- 273 goal_name_arity(Goal, Name, Arity), 274 current_predicate(system:Name/Arity), % avoid autoloading 275 predicate_property(system:Goal, built_in), 276 !. 277 278 279 /******************************** 280 * TOPLEVEL * 281 ********************************/ 282 283verbose(Src) :- 284 \+ xoption(Src, silent(true)). 285 286:- thread_local 287 xref_input/2. % File, Stream
true (default false), emit warning messages.all, non_iso or non_built_in (default).store, comments are stored into the
database as if the file was compiled. If collect, comments are
entered to the xref database and made available through
xref_mode/2 and xref_comment/4. If ignore, comments are simply
ignored. Default is to collect comments.true).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)).
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(). 442 443with_xref(Goal) :- 444 setup_call_cleanup( 445 push_prolog_flag(xref, true), 446 Goal, 447 pop_prolog_flag(xref)).
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).
477xref_input_stream(Stream) :-
478 xref_input(_, Var),
479 !,
480 Stream = Var.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).
530xref_set_prolog_flag(Flag, Value, Src, Line) :- 531 atom(Flag), 532 !, 533 assertz(xflag(Flag, Value, Src, Line)). 534xref_set_prolog_flag(_, _, _, _).
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 /******************************* 572 * READ RESULTS * 573 *******************************/
579xref_current_source(Source) :-
580 source(Source, _Time).
587xref_done(Source, Time) :-
588 prolog_canonical_source(Source, Src),
589 source(Src, Time).Called-By pairs. The xref_called/5 version may return
duplicate Called-By if Called is called from multiple clauses in
By, but at most one call per clause.
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).
include(File)) directive.
dynamic(Location)thread_local(Location)multifile(Location)public(Location)local(Location)foreign(Location)constraint(Location)imported(From)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).
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).
692xref_exported(Source, Called) :-
693 prolog_canonical_source(Source, Src),
694 exported(Called, Src).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).
717xref_uses_file(Source, Spec, Path) :-
718 prolog_canonical_source(Source, Src),
719 uses_file(Spec, Src, Path).
729xref_op(Source, Op) :-
730 prolog_canonical_source(Source, Src),
731 xop(Src, Op).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.
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.
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(_).
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 /******************************* 871 * PROCESS * 872 *******************************/
887process(Expanded, Comments, Term0, VarNames, TermPos, Src, EOF) :- 888 is_list(Expanded), % term_expansion into list. 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).
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(_,_,_))).
922process(Var, _) :- 923 var(Var), 924 !. % Warn? 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 /******************************* 966 * COMMENTS * 967 *******************************/
975xref_comments([], _Pos, _Term, _VarNames, _Src). 976:- if(current_predicate(parse_comment/5)). 977xref_comments([Pos-Comment|T], TermPos, Term, VarNames, Src) :- 978 ( Pos @> TermPos % comments inside term 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 993last_comment([], _). 994last_comment([Pos-_|_], TermPos) :- 995 Pos @> TermPos. 996 997assert_comments([], _). 998assert_comments([H|T], Src) :- 999 assert_comment(H, Src), 1000 assert_comments(T, Src). 1001 1002assert_comment(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.
1037xref_comment(Source, Title, Comment) :-
1038 canonical_source(Source, Src),
1039 module_comment(Src, Title, Comment).
1045xref_comment(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 ).xpce(Class, Kind, Name) for the members of xpce classes.
1058xref_object_comment(Source, Object, Summary, Comment) :-
1059 canonical_source(Source, Src),
1060 object_comment(Object, Src, Summary, Comment).
1067xref_object_signature(Source, Object, Signature) :-
1068 canonical_source(Source, Src),
1069 object_signature(Object, Src, Signature).
1076xref_mode(Source, Mode, Det) :-
1077 canonical_source(Source, Src),
1078 pred_mode(Mode, Src, Det).1085xref_option(Source, Option) :- 1086 canonical_source(Source, Src), 1087 xoption(Src, Option). 1088 1089 1090 /******************************** 1091 * DIRECTIVES * 1092 ********************************/ 1093 1094process_directive(Var, _) :- 1095 var(Var), 1096 !. % error, but that isn't our business 1097process_directive(Dir, _Src) :- 1098 debug(xref(directive), 'Processing :- ~q', [Dir]), 1099 fail. 1100process_directive((A,B), Src) :- % TBD: what about other control 1101 !, 1102 process_directive(A, Src), % structures? 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). % hack for handling boot/init.pl 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 % can this happen? 1182 ). 1183process_directive(pce_expansion:push_compile_operators, _) :- 1184 '$current_source_module'(SM), 1185 call(pce_expansion:push_compile_operators(SM)). % call to avoid xref 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).
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) :- % swapped arguments for maplist 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]) :- % 0 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]) :- % I --> H+I 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 /******************************** 1282 * BODY * 1283 ********************************/
1292xref_meta(Source, Head, Called) :-
1293 canonical_source(Source, Src),
1294 xref_meta_src(Head, Called, Src).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). % built-in 1350apply_pred(maplist). % library(apply_macros) 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]). % library(debug) 1424xref_meta(assertion(G), [G]). % library(debug) 1425xref_meta(freeze(_, G), [G]). 1426xref_meta(when(C, A), [C, A]). 1427xref_meta(time(G), [G]). % development system 1428xref_meta(call_time(G, _), [G]). % development system 1429xref_meta(call_time(G, _, _), [G]). % development system 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]). % library(solution_sequences) 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 % XPCE meta-predicates 1457xref_meta(pce_global(_, new(_)), _) :- !, fail. 1458xref_meta(pce_global(_, B), [B+1]). 1459xref_meta(ifmaintainer(G), [G]). % used in manual 1460xref_meta(listen(_, G), [G]). % library(broadcast) 1461xref_meta(listen(_, _, G), [G]). 1462xref_meta(in_pce_thread(G), [G]). 1463 1464xref_meta(G, Meta) :- % call user extensions 1465 prolog:meta_goal(G, Meta). 1466xref_meta(G, Meta) :- % Generated from :- meta_predicate 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, _).
1488head_of(Var, _) :- 1489 var(Var), !, fail. 1490head_of((Head :- _), Head). 1491head_of(Head, Head).
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(_,_,_,_)).
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).
We limit the number of explored paths to 100 to avoid getting trapped in this analysis.
1586process_body(Body, Origin, Src) :-
1587 forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
1588 true).true if there was a
partial evalation inside Goal that has bound variables.1595process_goal(Var, _, _, _) :- 1596 var(Var), 1597 !. 1598process_goal(_:Goal, _, _, _) :- 1599 var(Goal), 1600 !. 1601process_goal(Goal, Origin, Src, P) :- 1602 Goal = (_,_), % problems 1603 !, 1604 phrase(conjunction(Goal), Goals), 1605 process_conjunction(Goals, Origin, Src, P). 1606process_goal(Goal, Origin, Src, _) :- % Final disjunction, no 1607 Goal = (_;_), % problems 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 (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).
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 !. % terminal 1767process_dcg_goal(List, _Origin, _Src, _) :- 1768 string(List), 1769 !. % terminal 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, _, _) :- !. % catch variables 1804process_assert((_:-Body), Origin, Src) :- 1805 !, 1806 process_body(Body, Origin, Src). 1807process_assert(_, _, _).
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 ).
T = hello(X),
findall(T, T, List),
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 /******************************* 1847 * PLUNIT SUPPORT * 1848 *******************************/ 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 /******************************* 1859 * XPCE STUFF * 1860 *******************************/ 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, _, _) :- !. % TBD: Calls on other modules! 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 /******************************** 1943 * INCLUDED MODULES * 1944 ********************************/
1948process_use_module(_Module:_Files, _, _) :- !. % loaded in another module 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) :- % bit special 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) % hacky 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(_) % hack!? 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).
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 ).2027load_module_if_needed(File) :- 2028 prolog:no_autoload_module(File), 2029 !, 2030 use_module(File, []). 2031load_module_if_needed(_). 2032 2033prologno_autoload_module(library(apply_macros)). 2034prologno_autoload_module(library(arithmetic)). 2035prologno_autoload_module(library(record)). 2036prologno_autoload_module(library(persistency)). 2037prologno_autoload_module(library(pldoc)). 2038prologno_autoload_module(library(settings)). 2039prologno_autoload_module(library(debug)). 2040prologno_autoload_module(library(plunit)). 2041prologno_autoload_module(library(macros)). 2042prologno_autoload_module(library(yall)).
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 ).
[] for
.qlf files.[] for .qlf files.The information collected by this predicate is cached. The cached data is considered valid as long as the modification time of the file does not change.
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).These predicates fail if File is not a module-file.
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, []).
true, ignore (syntax) errors. If not specified the default
is inherited from xref_source/2.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).
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).
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].
INDEX.pl file in the same
directory.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 /******************************* 2399 * INCLUDE * 2400 *******************************/ 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(_, _).
include(File) referenced file. Note that we cannot
use prolog_open_source/2 because we should not safe/restore
the lexical context.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) % deal with non-file input 2443 ; include_encoding(Enc, Options), 2444 open(Path, read, In, Options) 2445 ), E, 2446 ( '$pop_input_context', throw(E))), 2447 catch(( peek_char(In, #) % Deal with #! script 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'.
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 /******************************* 2488 * CHR SUPPORT * 2489 *******************************/ 2490 2491/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2492This part of the file supports CHR. Our choice is between making special 2493hooks to make CHR expansion work and then handle the (complex) expanded 2494code or process the CHR source directly. The latter looks simpler, 2495though I don't like the idea of adding support for libraries to this 2496module. A file is supposed to be a CHR file if it uses a 2497use_module(library(chr) or contains a :- constraint/1 directive. As an 2498extra bonus we get the source-locations right :-) 2499- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 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 !. % Illegal. Warn? 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 /******************************** 2578 * PHASE 1 ASSERTIONS * 2579 ********************************/
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) % explicit call to own module 2602 -> assert_called(Src, Origin, G, Line) 2603 ; called(M:G, Src, Origin, Cond, Line) % already registered 2604 -> true 2605 ; hide_called(M:G, Src) % not interesting (now) 2606 -> true 2607 ; generalise(Origin, OTerm), 2608 generalise(G, GTerm) 2609 -> assert(called(M:GTerm, Src, OTerm, Cond, Line)) 2610 ; true 2611 ) 2612 ; true % call to variable module 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 ).
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)).
true, re-export the
imported predicates.
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)).
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(_, _).
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).
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 ).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).
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).
call(Closure, PI,
Src). Handles both lists of specifications and (PI,...)
specifications.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, _) % dynamic after thread_local has 2863 -> true % no effect 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) :- % :- multifile(Spec) 2874 pi_to_head(PI, Term), 2875 current_source_line(Line), 2876 assert(multifile(Term, Src, Line)). 2877 2878assert_public(PI, Src) :- % :- public(Spec) 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) :- % :- export(Spec) 2885 pi_to_head(PI, Term), 2886 !, 2887 assert(exported(Term, Src)).
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(_, _, _, -, _) :- !. % :- pce_extend_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 /******************************** 2940 * UTILITIES * 2941 ********************************/
2947generalise(Var, Var) :- 2948 var(Var), 2949 !. % error? 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 /******************************* 2978 * SOURCE MANAGEMENT * 2979 *******************************/ 2980 2981/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2982This section of the file contains hookable predicates to reason about 2983sources. The built-in code here can only deal with files. The XPCE 2984library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we 2985can do cross-referencing on PceEmacs edit buffers. Other examples for 2986hooking can be databases, (HTTP) URIs, etc. 2987- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2988 2989:- multifile 2990 prolog:xref_source_directory/2, % +Source, -Dir 2991 prolog:xref_source_file/3. % +Spec, -Path, +Options
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), % handle absolute /file/to/source.pl without sources 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).
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 !.
3100canonical_source(Source, Src) :-
3101 ( ground(Source)
3102 -> prolog_canonical_source(Source, Src)
3103 ; Source = Src
3104 ).name()
goals.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 /******************************* 3141 * MESSAGES * 3142 *******************************/< 3143 3144:- multifile prolog:message//1. 3145 3146prologmessage(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 ]
Prolog cross-referencer data collection
This library collects information on defined and used objects in Prolog source files. Typically these are predicates, but we expect the library to deal with other types of objects in the future. The library is a building block for tools doing dependency tracking in applications. Dependency tracking is useful to reveal the structure of an unknown program or detect missing components at compile time, but also for program transformation or minimising a program saved state by only saving the reachable objects.
The library is exploited by two graphical tools in the SWI-Prolog environment: the XPCE front-end started by gxref/0, and library(prolog_colour), which exploits this library for its syntax highlighting.
For all predicates described below, Source is the source that is processed. This is normally a filename in any notation acceptable to the file loading predicates (see load_files/2). Input handling is done by the library(prolog_source), which may be hooked to process any source that can be translated into a Prolog stream holding Prolog source text. Callable is a callable term (see callable/1). Callables do not carry a module qualifier unless the referred predicate is not in the module defined by Source.