1c334e6f352c4faa49068339ae678daba47caf20
[nit.git] / contrib / pep8analysis / src / pep8analysis.nit
1 module pep8analysis
2
3 import backbone
4 import ast
5 import model
6 import cfg
7 import flow_analysis
8
9 redef class AnalysisManager
10 var opt_help = new OptionBool("Display this help message", "--help","-h")
11 var opt_quiet = new OptionBool("Do not show notes", "--quiet","-q")
12 fun quiet: Bool do return opt_quiet.value
13 fun verbose: Bool do return not opt_quiet.value
14
15 var opt_output = new OptionString("Output directory", "--output", "-o")
16
17 redef init
18 do
19 super
20
21 opts.add_option(opt_help)
22 opts.add_option(opt_quiet)
23 opts.add_option(opt_output)
24 end
25
26 fun run
27 do
28 opts.parse(args)
29 var files = opts.rest
30
31 if files.is_empty or opt_help.value then
32 print "Usage: pep8analysis [options] file.pep [other_file.pep [...]]"
33 print "Options:"
34 opts.usage
35 return
36 end
37
38 var dir = opt_output.value
39 if dir == null then dir = "out"
40 if not dir.file_exists then dir.mkdir
41
42 # Parsing
43 for filename in files do
44 reset # noter
45
46 if verbose then print "Analyzing {filename}"
47 if not filename.file_exists then
48 print "Target file \"{filename}\" does not exist."
49 exit 1
50 end
51 var ast = build_ast( filename )
52 assert ast != null
53
54 if failed then continue
55
56 var mangled_filename = filename.replace("/","-").replace("..","up")
57 if opt_ast.value then
58 var printer = new ASTPrinter
59 printer.enter_visit(ast)
60 var of = new OFStream.open("{dir}/{mangled_filename.replace(".pep", ".ast.dot")}")
61 of.write printer.str
62 of.close
63 end
64
65 # Build program model
66 var model = build_model(ast)
67
68 if failed then continue
69
70 if model.lines.is_empty then
71 fatal_error( ast, "This programs appears empty" )
72 continue
73 end
74
75 # Create CFG
76 var cfg = build_cfg(model)
77
78 if opt_cfg.value or opt_cfg_long.value then
79 var of = new OFStream.open("{dir}/{mangled_filename.replace(".pep", ".cfg.dot")}")
80 cfg.print_dot(of, opt_cfg_long.value)
81 of.close
82 end
83
84 if failed then continue
85
86 # Run analyses
87
88 ## Reaching defs
89 do_reaching_defs_analysis(cfg)
90
91 ## Range
92 do_range_analysis(ast, cfg)
93
94 ## Types
95 do_types_analysis(ast, cfg)
96
97 # Print results
98 var of = new OFStream.open("{dir}/{mangled_filename.replace(".pep",".analysis.dot")}")
99 cfg.print_dot(of, true)
100 of.close
101 end
102 if not opt_quiet.value then
103 print_notes
104 end
105 end
106 end
107
108 redef class Object
109 redef fun manager do return once new AnalysisManager
110 end
111
112 manager.run