Title: [101005] trunk/Tools
Revision
101005
Author
aro...@apple.com
Date
2011-11-22 08:52:44 -0800 (Tue, 22 Nov 2011)

Log Message

Teach prepare-ChangeLog how to find changed classes/methods/functions in Python files

Fixes <http://webkit.org/b/57008> prepare-ChangeLog doesn't find names of modified
classes/methods in Python source files

Reviewed by Dan Bates.

* Scripts/prepare-ChangeLog:
(get_function_line_ranges): Call get_function_line_ranges_for_python for files ending in .py
or that use python as their interpreter. Modified the code that extracts the interpreter to
ignore a leading "/usr/bin/env " in the interpreter line, as is common for our Python
scripts.
(get_function_line_ranges_for_python): Added. Does simple parsing of Python files to look
for class/def lines and generate ranges based on them.

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (101004 => 101005)


--- trunk/Tools/ChangeLog	2011-11-22 16:43:21 UTC (rev 101004)
+++ trunk/Tools/ChangeLog	2011-11-22 16:52:44 UTC (rev 101005)
@@ -1,3 +1,20 @@
+2011-11-22  Adam Roben  <aro...@apple.com>
+
+        Teach prepare-ChangeLog how to find changed classes/methods/functions in Python files
+
+        Fixes <http://webkit.org/b/57008> prepare-ChangeLog doesn't find names of modified
+        classes/methods in Python source files
+
+        Reviewed by Dan Bates.
+
+        * Scripts/prepare-ChangeLog:
+        (get_function_line_ranges): Call get_function_line_ranges_for_python for files ending in .py
+        or that use python as their interpreter. Modified the code that extracts the interpreter to
+        ignore a leading "/usr/bin/env " in the interpreter line, as is common for our Python
+        scripts.
+        (get_function_line_ranges_for_python): Added. Does simple parsing of Python files to look
+        for class/def lines and generate ranges based on them.
+
 2011-11-21  Yuta Kitamura  <yu...@chromium.org>
 
         [GTK] Enable WebSocket hybi tests

Modified: trunk/Tools/Scripts/prepare-ChangeLog (101004 => 101005)


--- trunk/Tools/Scripts/prepare-ChangeLog	2011-11-22 16:43:21 UTC (rev 101004)
+++ trunk/Tools/Scripts/prepare-ChangeLog	2011-11-22 16:52:44 UTC (rev 101005)
@@ -499,16 +499,18 @@
     return get_function_line_ranges_for_javascript($file_handle, $file_name) if $file_name =~ /\.js$/;
     return get_selector_line_ranges_for_css($file_handle, $file_name) if $file_name =~ /\.css$/;
     return get_function_line_ranges_for_perl($file_handle, $file_name) if $file_name =~ /\.p[lm]$/;
+    return get_function_line_ranges_for_python($file_handle, $file_name) if $file_name =~ /\.py$/;
 
     # Try to determine the source language based on the script interpreter.
 
     my $first_line = <$file_handle>;
     seek($file_handle, 0, 0);
 
-    return () unless $first_line =~ /^#!(\S+)/;
+    return () unless $first_line =~ m|^#!(?:/usr/bin/env\s+)?(\S+)|;
     my $interpreter = $1;
 
     return get_function_line_ranges_for_perl($file_handle, $file_name) if $interpreter =~ /perl$/;
+    return get_function_line_ranges_for_python($file_handle, $file_name) if $interpreter =~ /python$/;
 
     return ();
 }
@@ -1246,6 +1248,62 @@
     return @ranges;
 }
 
+# Read a file and get all the line ranges of the things that look like Python classes, methods, or functions.
+#
+# FIXME: Maybe we should use Python's ast module to do the parsing for us?
+#
+# Result is a list of triples: [ start_line, end_line, function ].
+
+sub get_function_line_ranges_for_python($$)
+{
+    my ($fileHandle, $fileName) = @_;
+
+    my @ranges;
+
+    my @scopeStack = ({ line => 0, indent => -1, name => undef });
+    while (<$fileHandle>) {
+        next unless /^(\s*)(\S.*)$/;
+        my $indent = length $1;
+        my $rest = $2;
+
+        my $scope = $scopeStack[-1];
+
+        if ($indent <= $scope->{indent}) {
+            # Find all the scopes that we have just exited.
+            my $i = 0;
+            for (; $i < @scopeStack; ++$i) {
+                last if $indent <= $scopeStack[$i]->{indent};
+            }
+            my @poppedScopes = splice @scopeStack, $i;
+
+            # For each scope that was just exited, add a range that goes from the start of that
+            # scope to the start of the next nested scope, or to the line just before this one for
+            # the innermost scope.
+            for ($i = 0; $i < @poppedScopes; ++$i) {
+                my $lineAfterEnd = $i + 1 == @poppedScopes ? $. : $poppedScopes[$i + 1]->{line};
+                push @ranges, [$poppedScopes[$i]->{line}, $lineAfterEnd - 1, $poppedScopes[$i]->{name}];
+            }
+            @scopeStack or warn "Popped off last scope at $fileName:$.\n";
+
+            # Set the now-current scope to start at the current line. Any lines within this scope
+            # before this point should already have been added to @ranges.
+            $scope = $scopeStack[-1];
+            $scope->{line} = $.;
+        }
+
+        next unless $rest =~ /(?:class|def)\s+(\w+)/;
+        my $name = $1;
+
+        my $fullName = $scope->{name} ? join('.', $scope->{name}, $name) : $name;
+        push @scopeStack, { line => $., indent => $indent, name => $fullName };
+    }
+
+    foreach my $range (@ranges) {
+        printf "%3d:%3d %s\n", $range->[0], $range->[1], $range->[2];
+    }
+    return @ranges;
+}
+
 # Read a file and get all the line ranges of the things that look like CSS selectors.  A selector is
 # anything before an opening brace on a line. A selector starts at the line containing the opening
 # brace and ends at the closing brace.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to