dialyzer_gui.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,545 行 · 第 1/4 页

ERL
1,545
字号
%% -*- erlang-indent-level: 2 -*-%%------------------------------------------------------------------------%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% Copyright 2006, Tobias Lindahl and Kostis Sagonas%% %%     $Id$%%%%%-----------------------------------------------------------------------%%% File    : dialyzer_gui.erl%%% Authors : Tobias Lindahl <tobiasl@csd.uu.se>%%%           Kostis Sagonas <kostis@it.uu.se>%%% Description : The graphical user interface for the Dialyzer tool.%%%%%% Created : 27 Apr 2004 by Tobias Lindahl <tobiasl@csd.uu.se>%%%------------------------------------------------------------------------module(dialyzer_gui).-export([start/1]).-include("dialyzer.hrl").-record(gui_state, {add_all, add_file, add_rec,		    chosen_box, analysis_pid, del_file,		    doc_plt, clear_chosen, clear_log, clear_warn, 		    empty_plt, fixpoint, init_plt, 		    user_plt, dir_entry, file_box, file_wd, gs, log, menu, mode,		    options, packer, run, stop, top, warnings_box,		    backend_pid}).-record(menu, {file_save_log, file_save_warn, file_quit, 	       help_about, help_manual, help_overview, help_warnings, 	       opts_supress_inline, opts_macros, opts_includes,	       plt_empty, plt_search_doc, plt_show_doc,	       warnings}).	       -record(mode, {start_byte_code, iter_fixpoint,	       start_src_code, iter_qad, dataflow, succ_typings, old_style}).start(DialyzerOptions = #options{}) ->  process_flag(trap_exit, true),  GS = gs:start(),  code:add_pathsa(["."]),  WH = [{width, 1000}, {height, 550}],  {ok,Host} = inet:gethostname(),  %% --------- Top Window --------------  TopWin = gs:window(GS, [{title, "Dialyzer "++?VSN++" @ "++Host},			  {configure, true},			  {default, listbox, {bg, white}},			  {default, editor, {bg, white}},			  {default, entry, {bg, white}},			  {default, button, {font, {helvetica, bold, 12}}},			  {default, label, {font, {helvetica, bold, 12}}}			  |WH]),  Packer = gs:frame(TopWin, [{packer_x, [{stretch, 3},{fixed, 200},					 {stretch, 7}]},			     {packer_y, [{fixed, 25}, {fixed, 20},					 {stretch, 1, 50},					 {fixed, 25}, {fixed, 20},					 {stretch, 1, 50},					 {fixed, 25}]}]),  %% --------- Chosen box --------------  gs:label(Packer, [{label, {text, "Directories or modules to analyze"}}, 		    {height, 20}, {pack_xy, {1,2}}]),  ChosenBox = gs:listbox(Packer, [{pack_xy, {1,3}},{vscroll, right},				{selectmode, multiple}]),  %% --------- File box --------------  gs:label(Packer, [{label, {text, "File"}}, {height, 20}, {pack_xy, {1,5}}]),  FilePacker = gs:frame(Packer, [{packer_x, [{fixed, 30}, {stretch, 1, 100}]},				 {packer_y, [{fixed, 25}, {stretch, 1, 25}]},				 {pack_xy, {1, 6}}]),  gs:label(FilePacker, [{label, {text, "Dir:"}}, {pack_xy, {1,1}}]),  DirEntry = gs:entry(FilePacker, [{height, 30}, {pack_xy, {2,1}},				   {keypress, true}]),  File = gs:listbox(FilePacker, [{pack_x, {1,2}}, {pack_y, 2},				 {selectmode, multiple}, {doubleclick, true}, 				 {vscroll, right}]),  %% --------- Options --------------  gs:label(Packer, [{label, {text, "Analysis Options"}}, 		    {height, 20}, {pack_xy, {2, 2}}]),  ModePacker = gs:frame(Packer, [{packer_x, [{fixed, 75},{fixed, 120}]},				 {packer_y, [{fixed, 20},{fixed, 20},					     {fixed, 20},					     %%{stretch, 1}, % empty space					     {fixed, 20}, {fixed, 20}, 					     {fixed, 20},					     {stretch, 1} % empty space					    ]},				 {bw, 10}, {relief, flat},				 {default, {radiobutton, {align, w}}},				 {default, {label, {align, w}}},				 {pack_xy, {2, 3}}]),  %% Bytecode vs. Source code  gs:label(ModePacker, [{label, {text, "File Type:"}},			{height, 20}, {pack_xy, {1,1}}]),  ModeByteCode = gs:radiobutton(ModePacker,				[{group, start_from},				 {label, {text,"ByteCode"}},				 {select, true},				 {pack_xy, {2,1}}]),  ModeSrcCode = gs:radiobutton(ModePacker,			       [{group, start_from},				{label, {text,"SourceCode"}},				{pack_xy, {2,2}}]),  %% Analysis Type  gs:label(ModePacker, [{label, {text, "Analysis:"}}, 			{height, 20}, {pack_xy, {1,4}}]),  ModeDataflow = gs:radiobutton(ModePacker,			      [{group, type},			       {label,{text,"Dataflow"}}, 			       {select, true},			       {pack_xy, {2,4}}]),  ModeSuccTypings = gs:radiobutton(ModePacker,			       [{group, type},				{label,{text,"Success Typings"}}, 				{pack_xy, {2,5}}]),  ModeOldStyle = gs:radiobutton(ModePacker,				[{group, type},				 {label,{text,"Old Style"}}, 				 {pack_xy, {2,6}}]),  Mode = #mode{start_byte_code=ModeByteCode,	       start_src_code=ModeSrcCode,	       dataflow=ModeDataflow,	       succ_typings=ModeSuccTypings,	       old_style=ModeOldStyle	      },  %% --------- Log box --------------  gs:label(Packer, [{label, {text, "Log"}}, {height, 20}, {pack_xy, {3,2}}]),  Log = gs:editor(Packer, [{pack_x, 3}, {pack_y, 3}, {enable, false},			   {font, {courier, 12}}, {vscroll, right},			   {wrap, word}]),  %% --------- Warnings box --------------  gs:label(Packer, [{label, {text, "Warnings"}},{height, 20},{pack_xy, {3,5}}]),  WarningsBox = gs:editor(Packer, [{pack_x, {2,3}}, {pack_y, 6},				   {enable, false},				   {font, {courier, 12}},{vscroll, right},				   {wrap, word}]),  %% --------- Buttons --------------  ButtonPackerHighLeft =     gs:frame(Packer, [{packer_x, [{fixed, 50},				  {fixed, 65},				  {stretch,1}]}, % empty space		      {pack_xy, {1,4}}]),  ButtonPackerHighRight =     gs:frame(Packer, [{packer_x, [{fixed, 70},				  {fixed, 70},				  {stretch,1}]}, % empty space		      {pack_xy, {3,4}}]),  ButtonPackerLowLeft =     gs:frame(Packer, [{packer_x, [{fixed, 50},				  {fixed, 60},				  {fixed, 110},				  {stretch,1}]}, % empty space		      {pack_xy, {1,7}}]),  ButtonPackerLowRight =     gs:frame(Packer, [{packer_x, [{fixed, 70},				  {fixed, 70},				  {stretch,1},% empty space				  {fixed, 70},				  {fixed, 70}]}, 		      {pack_x, {2,3}}, {pack_y, 7}]),  WHButton = [{width, 60},{height, 20}],  AddFile = gs:button(ButtonPackerLowLeft, [{pack_xy, {1,1}}, 					    {label, {text,"Add"}}|WHButton]),  AddAll = gs:button(ButtonPackerLowLeft, [{pack_xy, {2,1}}, 					   {label, {text,"Add All"}}|WHButton]),  AddRec = gs:button(ButtonPackerLowLeft, [{pack_xy, {3,1}},                                            {label, {text,"Add Recursively"}}                                           |WHButton]),  DelFile = gs:button(ButtonPackerHighLeft, [{pack_xy, {1,1}}, 					    {label, {text,"Delete"}}|WHButton]),  ClearChosen = gs:button(ButtonPackerHighLeft, [{pack_xy, {2,1}},					         {label, {text,"Delete All"}}					         |WHButton]),  ClearLog = gs:button(ButtonPackerHighRight, [{pack_xy, {1,1}}, 					       {label, {text,"Clear Log"}}					       |WHButton]),  ClearWarn = gs:button(ButtonPackerLowRight, [{pack_xy, {1,1}}, 					       {label, {text,"Clear Warn"}}					       |WHButton]),  Run = gs:button(ButtonPackerLowRight, [{pack_xy, {4,1}},					 {label, {text,"Run"}}|WHButton]),  Stop = gs:button(ButtonPackerLowRight, [{pack_xy, {5,1}}, {enable, false}, 					  {label, {text,"Stop"}}|WHButton]),  %% --------- Menu --------------    MenuBar = gs:menubar(TopWin, []),  %% File Menu  MenuBarFile = gs:menubutton(MenuBar, [{label,{text,"File"}}]),  MenuFile = gs:menu(MenuBarFile, []),  MenuFileSaveWarn = gs:menuitem(MenuFile, [{label,{text,"Save Warnings"}}]),  MenuFileSaveLog = gs:menuitem(MenuFile, [{label,{text,"Save Log"}}]),  MenuFileQuit = gs:menuitem(MenuFile, [{label,{text,"Quit"}}]),  %% Warnings Menu  MenuBarWarn = gs:menubutton(MenuBar, [{label,{text,"Warnings"}}]),  MenuWarn = gs:menu(MenuBarWarn, []),  MenuWarnMatch = gs:menuitem(MenuWarn, [{label, {text, "Match failures"}}, 					 {itemtype, check}, {select, true}]),  MenuWarnFailingCall = gs:menuitem(MenuWarn, 				    [{label, {text, "Failing function calls"}}, 				     {itemtype, check}, {select, true}]),  MenuWarnFunApp = gs:menuitem(MenuWarn, [{label, 					   {text, "Bad fun-applications"}}, 					  {itemtype, check}, {select, true}]),  MenuWarnLists = gs:menuitem(MenuWarn, [{label, {text, "Improper list constructions"}}, 					 {itemtype, check}, {select, true}]),  MenuWarnGuards = gs:menuitem(MenuWarn, [{label, {text, "Failing guards"}}, 					  {itemtype, check}, {select, true}]),  MenuWarnEq = gs:menuitem(MenuWarn, [{label, {text, "Failing term comparisons"}}, 				      {itemtype, check}, {select, true}]),  MenuWarnNotCalled = gs:menuitem(MenuWarn, 				  [{label, {text, "Unused functions"}}, 				   {itemtype, check}, {select, true}]),  MenuWarnTupleAsFun = gs:menuitem(MenuWarn, [{label, 					       {text, "Tuple used as fun"}}, 					      {itemtype, check}, 					      {select, true}]),  MenuWarnBeam = gs:menuitem(MenuWarn, [{label, {text, "Unsafe BEAM code"}}, 					{itemtype, check}, {select, true}]),  MenuWarnReturnOnlyExit = gs:menuitem(MenuWarn,				       [{label, 					 {text, "Error handling functions"}},					{itemtype, check}, {select, false}]),  MenuWarnReturnNoReturn = gs:menuitem(MenuWarn,				       [{label, 					 {text, "Functions of no return"}},					{itemtype, check}, {select, true}]),    MenuWarnCallNonExported = gs:menuitem(MenuWarn,					[{label, 					  {text,"Call to unexported function"}},					 {itemtype, check}, {select, true}]),      %% PLT Menu  MenuBarPLT = gs:menubutton(MenuBar, [{label, {text,"PLT"}}]),  MenuPLT = gs:menu(MenuBarPLT, []),  MenuPLTEmpty = gs:menuitem(MenuPLT, [{label,{text,"Init with empty PLT"}},				       {itemtype, check}, {select, false}]),  MenuPLTShow = gs:menuitem(MenuPLT, [{label,{text,"Show contents"}}]),  MenuPLTSearch = gs:menuitem(MenuPLT, [{label,{text,"Search contents"}}]),  %% Options Menu  MenuBarOpts = gs:menubutton(MenuBar, [{label,{text,"Options"}}]),  MenuOpts = gs:menu(MenuBarOpts, []),  MenuOptsCheckInline = gs:menuitem(MenuOpts, 				    [{label, {text, "Ignore inline-compiled bytecode"}}, 				     {itemtype, check}, {select, false}]),  MenuOptsMacros = gs:menuitem(MenuOpts,[{label, {text, "Manage Macro Definitions"}}]),  MenuOptsIncludes = gs:menuitem(MenuOpts, [{label, {text, "Manage Include Directories"}}]),    %% Help  MenuBarHelp = gs:menubutton(MenuBar, [{label,{text,"Help"}}, {side, right}]),  MenuHelp = gs:menu(MenuBarHelp, []),  MenuHelpOverview = gs:menuitem(MenuHelp, [{label,{text,"Overview"}}]),  MenuHelpManual = gs:menuitem(MenuHelp, [{label,{text,"Manual"}}]),  MenuHelpWarnings = gs:menuitem(MenuHelp, [{label,{text,"Warnings"}}]),  MenuHelpAbout = gs:menuitem(MenuHelp, [{label,{text,"About"}}]),    Warnings = [{?WARN_RETURN_NO_RETURN, MenuWarnReturnNoReturn},	      {?WARN_RETURN_ONLY_EXIT, MenuWarnReturnOnlyExit},	      {?WARN_NOT_CALLED, MenuWarnNotCalled},	      {?WARN_NON_PROPER_LIST, MenuWarnLists},	      {?WARN_TUPLE_AS_FUN, MenuWarnTupleAsFun},	      {?WARN_FUN_APP, MenuWarnFunApp},	      {?WARN_MATCHING, MenuWarnMatch},	      {?WARN_COMP, MenuWarnEq},	      {?WARN_GUARDS, MenuWarnGuards},	      {?WARN_OLD_BEAM, MenuWarnBeam},	      {?WARN_FAILING_CALL, MenuWarnFailingCall},	      {?WARN_CALLGRAPH, MenuWarnCallNonExported}	     ],  init_warnings(Warnings, DialyzerOptions#options.legal_warnings),  Menu = #menu{file_quit=MenuFileQuit,	       plt_empty=MenuPLTEmpty,	       help_overview=MenuHelpOverview,	       help_manual=MenuHelpManual,	       help_about=MenuHelpAbout,	       help_warnings=MenuHelpWarnings,	       opts_supress_inline=MenuOptsCheckInline,	       opts_macros=MenuOptsMacros,	       opts_includes=MenuOptsIncludes,	       plt_search_doc=MenuPLTSearch,	       plt_show_doc=MenuPLTShow,	       file_save_log=MenuFileSaveLog,	       file_save_warn=MenuFileSaveWarn,	       warnings=Warnings},  %% --------- Init --------------  gs:config(TopWin, {map, true}),  gs:config(Packer, WH),  {ok, CWD} = file:get_cwd(),    EmptyPlt = dialyzer_plt:new(dialyzer_empty_plt),  InitPlt0 = DialyzerOptions#options.init_plt,  InitPlt = dialyzer_plt:from_file(dialyzer_init_plt, InitPlt0),  State = #gui_state{add_all=AddAll,		     add_file=AddFile, 		     add_rec=AddRec,		     chosen_box=ChosenBox, 		     clear_chosen=ClearChosen, 		     clear_log=ClearLog, 		     clear_warn=ClearWarn, 		     del_file=DelFile, 		     dir_entry=DirEntry,		     empty_plt=EmptyPlt,		     file_box=File, 		     file_wd=CWD,		     gs=GS, 		     init_plt=InitPlt,		     log=Log, 		     menu=Menu,		     mode=Mode,		     options=DialyzerOptions,		     packer=Packer, 		     run=Run,		     stop=Stop,		     top=TopWin, 		     warnings_box=WarningsBox},  NewState = change_dir_or_add_file(State, "."),  gui_loop(NewState).%% ----------------------------------------------------------------%%%%  Main GUI Loop%%gui_loop(State = #gui_state{}) ->  TopWin = State#gui_state.top,  Packer = State#gui_state.packer,  ChosenBox = State#gui_state.chosen_box,  File = State#gui_state.file_box,  DirEntry = State#gui_state.dir_entry,  Run = State#gui_state.run,  AddFile = State#gui_state.add_file,  AddAll = State#gui_state.add_all,  AddRec = State#gui_state.add_rec,  DelFile = State#gui_state.del_file,  ClearChosen = State#gui_state.clear_chosen,  ClearLog = State#gui_state.clear_log,  ClearWarn = State#gui_state.clear_warn,  Stop = State#gui_state.stop,  Log = State#gui_state.log,  BackendPid = State#gui_state.backend_pid,  Options = State#gui_state.options,  %% --- Menu ---  Menu = State#gui_state.menu,  Quit = Menu#menu.file_quit,  Overview = Menu#menu.help_overview,  Manual = Menu#menu.help_manual,  HelpWarnings = Menu#menu.help_warnings,  About = Menu#menu.help_about,  SaveLog = Menu#menu.file_save_log,  SaveWarn = Menu#menu.file_save_warn,  SearchPlt = Menu#menu.plt_search_doc,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?