OLD | NEW |
| (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 """Presubmit script for Chromium JS resources. | |
6 | |
7 See chrome/browser/PRESUBMIT.py | |
8 """ | |
9 | |
10 import regex_check | |
11 | |
12 | |
13 class JSChecker(object): | |
14 def __init__(self, input_api, output_api, file_filter=None): | |
15 self.input_api = input_api | |
16 self.output_api = output_api | |
17 self.file_filter = file_filter | |
18 | |
19 def RegexCheck(self, line_number, line, regex, message): | |
20 return regex_check.RegexCheck( | |
21 self.input_api.re, line_number, line, regex, message) | |
22 | |
23 def ChromeSendCheck(self, i, line): | |
24 """Checks for a particular misuse of 'chrome.send'.""" | |
25 return self.RegexCheck(i, line, r"chrome\.send\('[^']+'\s*(, \[\])\)", | |
26 'Passing an empty array to chrome.send is unnecessary') | |
27 | |
28 def CommentIfAndIncludeCheck(self, line_number, line): | |
29 return self.RegexCheck(line_number, line, r'(?<!\/\/ )(<if|<include) ', | |
30 '<if> or <include> should be in a single line comment with a space ' + | |
31 'after the slashes. Examples:\n' + | |
32 ' // <include src="...">\n' + | |
33 ' // <if expr="chromeos">\n' + | |
34 ' // </if>\n') | |
35 | |
36 def ConstCheck(self, i, line): | |
37 """Check for use of the 'const' keyword.""" | |
38 if self.input_api.re.search(r'\*\s+@const', line): | |
39 # Probably a JsDoc line | |
40 return '' | |
41 | |
42 return self.RegexCheck(i, line, r'(?:^|\s|\()(const)\s', | |
43 'Use /** @const */ var varName; instead of const varName;') | |
44 | |
45 def EndJsDocCommentCheck(self, i, line): | |
46 msg = 'End JSDoc comments with */ instead of **/' | |
47 def _check(regex): | |
48 return self.RegexCheck(i, line, regex, msg) | |
49 return _check(r'^\s*(\*\*/)\s*$') or _check(r'/\*\* @[a-zA-Z]+.* (\*\*/)') | |
50 | |
51 def ExtraDotInGenericCheck(self, i, line): | |
52 return self.RegexCheck(i, line, r"((?:Array|Object|Promise)\.<)", | |
53 "Don't use a dot after generics (Object.<T> should be Object<T>).") | |
54 | |
55 def GetElementByIdCheck(self, i, line): | |
56 """Checks for use of 'document.getElementById' instead of '$'.""" | |
57 return self.RegexCheck(i, line, r"(document\.getElementById)\('", | |
58 "Use $('id') or getSVGElement('id') from chrome://resources/js/util.js " | |
59 "instead of document.getElementById('id')") | |
60 | |
61 def InheritDocCheck(self, i, line): | |
62 """Checks for use of '@inheritDoc' instead of '@override'.""" | |
63 return self.RegexCheck(i, line, r"\* (@inheritDoc)", | |
64 "@inheritDoc is deprecated, use @override instead") | |
65 | |
66 def PolymerLocalIdCheck(self, i, line): | |
67 """Checks for use of element.$.localId.""" | |
68 return self.RegexCheck(i, line, r"(?<!this)(\.\$)[\[\.]", | |
69 "Please only use this.$.localId, not element.$.localId") | |
70 | |
71 def WrapperTypeCheck(self, i, line): | |
72 """Check for wrappers (new String()) instead of builtins (string).""" | |
73 return self.RegexCheck(i, line, | |
74 r"(?:/\*)?\*.*?@(?:param|return|type) ?" # /** @param/@return/@type | |
75 r"{[^}]*\b(String|Boolean|Number)\b[^}]*}", # {(Boolean|Number|String)} | |
76 "Don't use wrapper types (i.e. new String() or @type {String})") | |
77 | |
78 def VarNameCheck(self, i, line): | |
79 """See the style guide. http://goo.gl/eQiXVW""" | |
80 return self.RegexCheck(i, line, | |
81 r"var (?!g_\w+)(_?[a-z][a-zA-Z]*[_$][\w_$]*)(?<! \$)", | |
82 "Please use var namesLikeThis <https://goo.gl/eQiXVW>") | |
83 | |
84 def _GetErrorHighlight(self, start, length): | |
85 """Takes a start position and a length, and produces a row of '^'s to | |
86 highlight the corresponding part of a string. | |
87 """ | |
88 return start * ' ' + length * '^' | |
89 | |
90 def RunChecks(self): | |
91 """Check for violations of the Chromium JavaScript style guide. See | |
92 https://chromium.googlesource.com/chromium/src/+/master/styleguide/web/we
b.md#JavaScript | |
93 """ | |
94 results = [] | |
95 | |
96 affected_files = self.input_api.change.AffectedFiles( | |
97 file_filter=self.file_filter, | |
98 include_deletes=False) | |
99 affected_js_files = filter(lambda f: f.LocalPath().endswith('.js'), | |
100 affected_files) | |
101 for f in affected_js_files: | |
102 error_lines = [] | |
103 | |
104 for i, line in enumerate(f.NewContents(), start=1): | |
105 error_lines += filter(None, [ | |
106 self.ChromeSendCheck(i, line), | |
107 self.CommentIfAndIncludeCheck(i, line), | |
108 self.ConstCheck(i, line), | |
109 self.GetElementByIdCheck(i, line), | |
110 self.EndJsDocCommentCheck(i, line), | |
111 self.ExtraDotInGenericCheck(i, line), | |
112 self.InheritDocCheck(i, line), | |
113 self.PolymerLocalIdCheck(i, line), | |
114 self.WrapperTypeCheck(i, line), | |
115 self.VarNameCheck(i, line), | |
116 ]) | |
117 | |
118 if error_lines: | |
119 error_lines = [ | |
120 'Found JavaScript style violations in %s:' % | |
121 f.LocalPath()] + error_lines | |
122 results.append(self.output_api.PresubmitError('\n'.join(error_lines))) | |
123 | |
124 if results: | |
125 results.append(self.output_api.PresubmitNotifyResult( | |
126 'See the JavaScript style guide at ' | |
127 'https://chromium.googlesource.com/chromium/src/+/master/styleguide/we
b/web.md#JavaScript')) | |
128 | |
129 return results | |
OLD | NEW |