Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: tools/checkdeps/java_checker.py

Issue 10790014: Add Java support to checkdeps.py (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Checker implementation that checks Java files.
6
7 If you import this module it will register itself with checker.Factory.
8 """
9
10 import fileinput
11 import os
12 import re
13 import sys
14
15 import checker
16
17
18 class JavaChecker(checker.Checker):
19 """Checker implementation for Java files.
20
21 The Checker interface uses real filesystem paths, but Java imports work in
22 terms of package names. To deal with this, we have an extra "prescan" pass
23 that reads all the .java files and builds a mapping of class name -> filename.
24 In CheckFile, we convert each import statement into a real filename, and check
25 that against the rules in the DEPS files.
26
27 Note that in Java you can always use classes in the same directory without an
28 explicit import statement, so these imports can't be blocked with DEPS files.
29 But that shouldn't be a problem, because same-package imports are pretty much
30 always correct by definition. (If we find a case where this is *not* correct,
31 it probably means the package is too big and needs to be split up.)
32
33 Properties:
34 _classmap: dict of fully-qualified Java class name -> filename
35 """
36
M-A Ruel 2012/07/17 14:23:20 EXTENSIONS = [ '.java', ]
Iain Merrick 2012/07/17 15:55:08 Done.
37 def __init__(self, *args):
38 super(JavaChecker, self).__init__(*args)
39 self._PrescanFiles()
40
41 def _PrescanFiles(self):
42 self._classmap = {}
M-A Ruel 2012/07/17 14:23:20 Define it in the __init__ function. Make sure your
Iain Merrick 2012/07/17 15:55:08 Done.
43 for root, dirs, files in os.walk(self._base_directory):
44 # Skip unwanted subdirectories. TODO(husky): it would be better to do this
45 # via the skip_child_includes flag in DEPS files. Maybe hoist this prescan
46 # logic into checkdeps.py itself?
47 for d in dirs:
48 # Skip hidden directories.
49 if d.startswith('.'):
50 dirs.remove(d)
51 # Skip the "out" directory, as dealing with generated files is awkward.
52 # We don't want paths like "out/Release/lib.java" in our DEPS files.
53 # TODO(husky): We need some way of determining the "real" path to
54 # a generated file -- i.e., where it would be in source control if
55 # it weren't generated.
56 if d == 'out':
57 dirs.remove(d)
58 # Skip third-party directories.
59 if d == 'third_party':
60 dirs.remove(d)
61 for f in files:
62 if f.endswith('.java'):
63 self._PrescanFile(os.path.join(root, f))
64
65 def _PrescanFile(self, filename):
M-A Ruel 2012/07/17 14:23:20 It's really more a filepath than a filename, but I
Iain Merrick 2012/07/18 13:22:12 Changed (and I just noticed that my search-and-rep
66 filename = os.path.relpath(filename, self._base_directory)
67 if self._verbose:
68 print 'Prescanning: ' + filename
69 f = fileinput.input(filename)
M-A Ruel 2012/07/17 14:23:20 I don't see why you are using fileinput at all her
Iain Merrick 2012/07/17 15:55:08 Just insufficient time spent searching the library
70 try:
71 short_class_name, _ = os.path.splitext(os.path.basename(filename))
M-A Ruel 2012/07/17 14:23:20 short_class_name = os.path.splitext(os.path.basena
72 for line in f:
73 for package in re.findall('^package ([\w\.]+);', line):
74 full_class_name = package + '.' + short_class_name
75 if full_class_name in self._classmap:
76 print 'WARNING: multiple definitions of %s:' % full_class_name
77 print ' ' + filename
78 print ' ' + self._classmap[full_class_name]
79 print
80 else:
81 self._classmap[full_class_name] = filename
82 return
83 print 'WARNING: no package definition found in %s' % filename
84 finally:
85 f.close()
86
87 def Extensions(self):
M-A Ruel 2012/07/17 14:23:20 Remove. This doesn't need to be a member function.
Iain Merrick 2012/07/17 15:55:08 Done.
88 return ['.java']
89
90 def CheckFile(self, rules, filename):
91 if self._verbose:
92 print 'Checking: ' + filename
93
94 result = ''
95 f = fileinput.input(filename)
M-A Ruel 2012/07/17 14:23:20 with fileinput.input(filename) as f: Remove the f
Iain Merrick 2012/07/17 15:55:08 Done.
96 try:
97 for line in f:
98 for clazz in re.findall('^import\s+(?:static\s+)?([\w\.]+)\s*;', line):
99 if clazz not in self._classmap:
100 # Importing a class from outside the Chromium tree. That's fine --
101 # it's probably a Java or Android system class.
102 continue
103 include_path = self._classmap[clazz]
104 (allowed, why_failed) = rules.DirAllowed(include_path)
105 if not allowed:
106 if self._verbose:
107 result += '\nFor ' + rules.__str__()
108 result += 'Illegal include: "%s"\n Because of %s\n' % (
109 include_path, why_failed)
110 if '{' in line:
111 # This is code, so we're finished reading imports for this file.
112 break
113
114 except IOError:
Iain Merrick 2012/07/18 13:22:12 Note: I've removed all IOError handling, as this i
115 if self._verbose:
116 print 'Unable to open file: ' + filename
117
118 finally:
119 f.close()
120
121 if len(result) == 0:
M-A Ruel 2012/07/17 14:23:20 if result: return result None is implicitly ret
Iain Merrick 2012/07/17 15:55:08 Done.
122 return None
123 return result
124
M-A Ruel 2012/07/17 14:23:20 Remove extra line.
Iain Merrick 2012/07/17 15:55:08 Done.
OLDNEW
« tools/checkdeps/cpp_checker.py ('K') | « tools/checkdeps/cpp_checker.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698