Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

362 lines
9.2 KiB

  1. package B::Lint;
  2. =head1 NAME
  3. B::Lint - Perl lint
  4. =head1 SYNOPSIS
  5. perl -MO=Lint[,OPTIONS] foo.pl
  6. =head1 DESCRIPTION
  7. The B::Lint module is equivalent to an extended version of the B<-w>
  8. option of B<perl>. It is named after the program B<lint> which carries
  9. out a similar process for C programs.
  10. =head1 OPTIONS AND LINT CHECKS
  11. Option words are separated by commas (not whitespace) and follow the
  12. usual conventions of compiler backend options. Following any options
  13. (indicated by a leading B<->) come lint check arguments. Each such
  14. argument (apart from the special B<all> and B<none> options) is a
  15. word representing one possible lint check (turning on that check) or
  16. is B<no-foo> (turning off that check). Before processing the check
  17. arguments, a standard list of checks is turned on. Later options
  18. override earlier ones. Available options are:
  19. =over 8
  20. =item B<context>
  21. Produces a warning whenever an array is used in an implicit scalar
  22. context. For example, both of the lines
  23. $foo = length(@bar);
  24. $foo = @bar;
  25. will elicit a warning. Using an explicit B<scalar()> silences the
  26. warning. For example,
  27. $foo = scalar(@bar);
  28. =item B<implicit-read> and B<implicit-write>
  29. These options produce a warning whenever an operation implicitly
  30. reads or (respectively) writes to one of Perl's special variables.
  31. For example, B<implicit-read> will warn about these:
  32. /foo/;
  33. and B<implicit-write> will warn about these:
  34. s/foo/bar/;
  35. Both B<implicit-read> and B<implicit-write> warn about this:
  36. for (@a) { ... }
  37. =item B<dollar-underscore>
  38. This option warns whenever $_ is used either explicitly anywhere or
  39. as the implicit argument of a B<print> statement.
  40. =item B<private-names>
  41. This option warns on each use of any variable, subroutine or
  42. method name that lives in a non-current package but begins with
  43. an underscore ("_"). Warnings aren't issued for the special case
  44. of the single character name "_" by itself (e.g. $_ and @_).
  45. =item B<undefined-subs>
  46. This option warns whenever an undefined subroutine is invoked.
  47. This option will only catch explicitly invoked subroutines such
  48. as C<foo()> and not indirect invocations such as C<&$subref()>
  49. or C<$obj-E<gt>meth()>. Note that some programs or modules delay
  50. definition of subs until runtime by means of the AUTOLOAD
  51. mechanism.
  52. =item B<regexp-variables>
  53. This option warns whenever one of the regexp variables $', $& or
  54. $' is used. Any occurrence of any of these variables in your
  55. program can slow your whole program down. See L<perlre> for
  56. details.
  57. =item B<all>
  58. Turn all warnings on.
  59. =item B<none>
  60. Turn all warnings off.
  61. =back
  62. =head1 NON LINT-CHECK OPTIONS
  63. =over 8
  64. =item B<-u Package>
  65. Normally, Lint only checks the main code of the program together
  66. with all subs defined in package main. The B<-u> option lets you
  67. include other package names whose subs are then checked by Lint.
  68. =back
  69. =head1 BUGS
  70. This is only a very preliminary version.
  71. =head1 AUTHOR
  72. Malcolm Beattie, mbeattie@sable.ox.ac.uk.
  73. =cut
  74. use strict;
  75. use B qw(walkoptree main_root walksymtable svref_2object parents
  76. OPf_WANT_LIST OPf_WANT OPf_STACKED G_ARRAY
  77. );
  78. my $file = "unknown"; # shadows current filename
  79. my $line = 0; # shadows current line number
  80. my $curstash = "main"; # shadows current stash
  81. # Lint checks
  82. my %check;
  83. my %implies_ok_context;
  84. BEGIN {
  85. map($implies_ok_context{$_}++,
  86. qw(scalar av2arylen aelem aslice helem hslice
  87. keys values hslice defined undef delete));
  88. }
  89. # Lint checks turned on by default
  90. my @default_checks = qw(context);
  91. my %valid_check;
  92. # All valid checks
  93. BEGIN {
  94. map($valid_check{$_}++,
  95. qw(context implicit_read implicit_write dollar_underscore
  96. private_names undefined_subs regexp_variables));
  97. }
  98. # Debugging options
  99. my ($debug_op);
  100. my %done_cv; # used to mark which subs have already been linted
  101. my @extra_packages; # Lint checks mainline code and all subs which are
  102. # in main:: or in one of these packages.
  103. sub warning {
  104. my $format = (@_ < 2) ? "%s" : shift;
  105. warn sprintf("$format at %s line %d\n", @_, $file, $line);
  106. }
  107. # This gimme can't cope with context that's only determined
  108. # at runtime via dowantarray().
  109. sub gimme {
  110. my $op = shift;
  111. my $flags = $op->flags;
  112. if ($flags & OPf_WANT) {
  113. return(($flags & OPf_WANT_LIST) ? 1 : 0);
  114. }
  115. return undef;
  116. }
  117. sub B::OP::lint {}
  118. sub B::COP::lint {
  119. my $op = shift;
  120. if ($op->name eq "nextstate") {
  121. $file = $op->file;
  122. $line = $op->line;
  123. $curstash = $op->stash->NAME;
  124. }
  125. }
  126. sub B::UNOP::lint {
  127. my $op = shift;
  128. my $opname = $op->name;
  129. if ($check{context} && ($opname eq "rv2av" || $opname eq "rv2hv")) {
  130. my $parent = parents->[0];
  131. my $pname = $parent->name;
  132. return if gimme($op) || $implies_ok_context{$pname};
  133. # Two special cases to deal with: "foreach (@foo)" and "delete $a{$b}"
  134. # null out the parent so we have to check for a parent of pp_null and
  135. # a grandparent of pp_enteriter or pp_delete
  136. if ($pname eq "null") {
  137. my $gpname = parents->[1]->name;
  138. return if $gpname eq "enteriter" || $gpname eq "delete";
  139. }
  140. warning("Implicit scalar context for %s in %s",
  141. $opname eq "rv2av" ? "array" : "hash", $parent->desc);
  142. }
  143. if ($check{private_names} && $opname eq "method") {
  144. my $methop = $op->first;
  145. if ($methop->name eq "const") {
  146. my $method = $methop->sv->PV;
  147. if ($method =~ /^_/ && !defined(&{"$curstash\::$method"})) {
  148. warning("Illegal reference to private method name $method");
  149. }
  150. }
  151. }
  152. }
  153. sub B::PMOP::lint {
  154. my $op = shift;
  155. if ($check{implicit_read}) {
  156. if ($op->name eq "match" && !($op->flags & OPf_STACKED)) {
  157. warning('Implicit match on $_');
  158. }
  159. }
  160. if ($check{implicit_write}) {
  161. if ($op->name eq "subst" && !($op->flags & OPf_STACKED)) {
  162. warning('Implicit substitution on $_');
  163. }
  164. }
  165. }
  166. sub B::LOOP::lint {
  167. my $op = shift;
  168. if ($check{implicit_read} || $check{implicit_write}) {
  169. if ($op->name eq "enteriter") {
  170. my $last = $op->last;
  171. if ($last->name eq "gv" && $last->gv->NAME eq "_") {
  172. warning('Implicit use of $_ in foreach');
  173. }
  174. }
  175. }
  176. }
  177. sub B::SVOP::lint {
  178. my $op = shift;
  179. if ($check{dollar_underscore} && $op->name eq "gvsv"
  180. && $op->gv->NAME eq "_")
  181. {
  182. warning('Use of $_');
  183. }
  184. if ($check{private_names}) {
  185. my $opname = $op->name;
  186. if ($opname eq "gv" || $opname eq "gvsv") {
  187. my $gv = $op->gv;
  188. if ($gv->NAME =~ /^_./ && $gv->STASH->NAME ne $curstash) {
  189. warning('Illegal reference to private name %s', $gv->NAME);
  190. }
  191. }
  192. }
  193. if ($check{undefined_subs}) {
  194. if ($op->name eq "gv"
  195. && $op->next->name eq "entersub")
  196. {
  197. my $gv = $op->gv;
  198. my $subname = $gv->STASH->NAME . "::" . $gv->NAME;
  199. no strict 'refs';
  200. if (!defined(&$subname)) {
  201. $subname =~ s/^main:://;
  202. warning('Undefined subroutine %s called', $subname);
  203. }
  204. }
  205. }
  206. if ($check{regexp_variables} && $op->name eq "gvsv") {
  207. my $name = $op->gv->NAME;
  208. if ($name =~ /^[&'`]$/) {
  209. warning('Use of regexp variable $%s', $name);
  210. }
  211. }
  212. }
  213. sub B::GV::lintcv {
  214. my $gv = shift;
  215. my $cv = $gv->CV;
  216. #warn sprintf("lintcv: %s::%s (done=%d)\n",
  217. # $gv->STASH->NAME, $gv->NAME, $done_cv{$$cv});#debug
  218. return if !$$cv || $done_cv{$$cv}++;
  219. my $root = $cv->ROOT;
  220. #warn " root = $root (0x$$root)\n";#debug
  221. walkoptree($root, "lint") if $$root;
  222. }
  223. sub do_lint {
  224. my %search_pack;
  225. walkoptree(main_root, "lint") if ${main_root()};
  226. # Now do subs in main
  227. no strict qw(vars refs);
  228. my $sym;
  229. local(*glob);
  230. while (($sym, *glob) = each %{"main::"}) {
  231. #warn "Trying $sym\n";#debug
  232. svref_2object(\*glob)->EGV->lintcv unless $sym =~ /::$/;
  233. }
  234. # Now do subs in non-main packages given by -u options
  235. map { $search_pack{$_} = 1 } @extra_packages;
  236. walksymtable(\%{"main::"}, "lintcv", sub {
  237. my $package = shift;
  238. $package =~ s/::$//;
  239. #warn "Considering $package\n";#debug
  240. return exists $search_pack{$package};
  241. });
  242. }
  243. sub compile {
  244. my @options = @_;
  245. my ($option, $opt, $arg);
  246. # Turn on default lint checks
  247. for $opt (@default_checks) {
  248. $check{$opt} = 1;
  249. }
  250. OPTION:
  251. while ($option = shift @options) {
  252. if ($option =~ /^-(.)(.*)/) {
  253. $opt = $1;
  254. $arg = $2;
  255. } else {
  256. unshift @options, $option;
  257. last OPTION;
  258. }
  259. if ($opt eq "-" && $arg eq "-") {
  260. shift @options;
  261. last OPTION;
  262. } elsif ($opt eq "D") {
  263. $arg ||= shift @options;
  264. foreach $arg (split(//, $arg)) {
  265. if ($arg eq "o") {
  266. B->debug(1);
  267. } elsif ($arg eq "O") {
  268. $debug_op = 1;
  269. }
  270. }
  271. } elsif ($opt eq "u") {
  272. $arg ||= shift @options;
  273. push(@extra_packages, $arg);
  274. }
  275. }
  276. foreach $opt (@default_checks, @options) {
  277. $opt =~ tr/-/_/;
  278. if ($opt eq "all") {
  279. %check = %valid_check;
  280. }
  281. elsif ($opt eq "none") {
  282. %check = ();
  283. }
  284. else {
  285. if ($opt =~ s/^no-//) {
  286. $check{$opt} = 0;
  287. }
  288. else {
  289. $check{$opt} = 1;
  290. }
  291. warn "No such check: $opt\n" unless defined $valid_check{$opt};
  292. }
  293. }
  294. # Remaining arguments are things to check
  295. return \&do_lint;
  296. }
  297. 1;