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

Side by Side Diff: third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py

Issue 2366153002: //third_party/WebKit clang-format preparation patch (Closed)
Patch Set: Created 4 years, 2 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
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 # 2 #
3 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved. 3 # Copyright (C) 2009, 2010, 2012 Google Inc. All rights reserved.
4 # Copyright (C) 2009 Torch Mobile Inc. 4 # Copyright (C) 2009 Torch Mobile Inc.
5 # Copyright (C) 2009 Apple Inc. All rights reserved. 5 # Copyright (C) 2009 Apple Inc. All rights reserved.
6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) 6 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
7 # 7 #
8 # Redistribution and use in source and binary forms, with or without 8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are 9 # modification, are permitted provided that the following conditions are
10 # met: 10 # met:
(...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 # they'll never need to wrap. 1530 # they'll never need to wrap.
1531 if ( # Ignore control structures. 1531 if ( # Ignore control structures.
1532 not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', f unction_call) 1532 not search(r'\b(if|for|foreach|while|switch|return|new|delete)\b', f unction_call)
1533 # Ignore pointers/references to functions. 1533 # Ignore pointers/references to functions.
1534 and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call) 1534 and not search(r' \([^)]+\)\([^)]*(\)|,$)', function_call)
1535 # Ignore pointers/references to arrays. 1535 # Ignore pointers/references to arrays.
1536 and not search(r' \([^)]+\)\[[^\]]+\]', function_call)): 1536 and not search(r' \([^)]+\)\[[^\]]+\]', function_call)):
1537 if search(r'\w\s*\([ \t](?!\s*\\$)', function_call): # a ( used for a fn call 1537 if search(r'\w\s*\([ \t](?!\s*\\$)', function_call): # a ( used for a fn call
1538 error(line_number, 'whitespace/parens', 4, 1538 error(line_number, 'whitespace/parens', 4,
1539 'Extra space after ( in function call') 1539 'Extra space after ( in function call')
1540 elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call): 1540 elif search(r'\([ \t]+(?!(\s*\\)|\()', function_call):
danakj 2016/09/29 20:54:04 All these whitespace things look redundant with th
1541 error(line_number, 'whitespace/parens', 2, 1541 error(line_number, 'whitespace/parens', 2,
1542 'Extra space after (') 1542 'Extra space after (')
1543 if (search(r'\w\s+\(', function_call)
1544 and not match(r'\s*(#|typedef)', function_call)):
1545 error(line_number, 'whitespace/parens', 4,
1546 'Extra space before ( in function call')
1547 # If the ) is followed only by a newline or a { + newline, assume it's 1543 # If the ) is followed only by a newline or a { + newline, assume it's
1548 # part of a control statement (if/while/etc), and don't complain 1544 # part of a control statement (if/while/etc), and don't complain
1549 if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call): 1545 if search(r'[^)\s]\s+\)(?!\s*$|{\s*$)', function_call):
1550 error(line_number, 'whitespace/parens', 2, 1546 error(line_number, 'whitespace/parens', 2,
1551 'Extra space before )') 1547 'Extra space before )')
1552 1548
1553 1549
1554 def is_blank_line(line): 1550 def is_blank_line(line):
1555 """Returns true if the given line is blank. 1551 """Returns true if the given line is blank.
1556 1552
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1869 # closing paren, without the opening paren, followed by an openi ng brace 1865 # closing paren, without the opening paren, followed by an openi ng brace
1870 # or colon (for initializer lists) we assume that it is the last line of 1866 # or colon (for initializer lists) we assume that it is the last line of
1871 # a function header. If we have a colon indented 4 spaces, it i s an 1867 # a function header. If we have a colon indented 4 spaces, it i s an
1872 # initializer list. 1868 # initializer list.
1873 exception = (match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)', 1869 exception = (match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
1874 previous_line) 1870 previous_line)
1875 or match(r' {4}:', previous_line)) 1871 or match(r' {4}:', previous_line))
1876 1872
1877 if not exception: 1873 if not exception:
1878 error(line_number, 'whitespace/blank_line', 2, 1874 error(line_number, 'whitespace/blank_line', 2,
1879 'Blank line at the start of a code block. Is this needed? ') 1875 'Blank line at the start of a code block. Is this needed? ')
danakj 2016/09/29 20:54:04 Doesn't clang-format kill these?
dcheng 2016/09/29 21:10:58 (This also applies to the previous comment) It doe
danakj 2016/09/29 21:19:56 okay. Given the complexity here I was not sure if
1880 # This doesn't ignore whitespace at the end of a namespace block 1876 # This doesn't ignore whitespace at the end of a namespace block
1881 # because that is too hard without pairing open/close braces; 1877 # because that is too hard without pairing open/close braces;
1882 # however, a special exception is made for namespace closing 1878 # however, a special exception is made for namespace closing
1883 # brackets which have a comment containing "namespace". 1879 # brackets which have a comment containing "namespace".
1884 # 1880 #
1885 # Also, ignore blank lines at the end of a block in a long if-else 1881 # Also, ignore blank lines at the end of a block in a long if-else
1886 # chain, like this: 1882 # chain, like this:
1887 # if (condition1) { 1883 # if (condition1) {
1888 # // Something followed by a blank line 1884 # // Something followed by a blank line
1889 # 1885 #
1890 # } else if (condition2) { 1886 # } else if (condition2) {
1891 # // Something else 1887 # // Something else
1892 # } 1888 # }
1893 if line_number + 1 < clean_lines.num_lines(): 1889 if line_number + 1 < clean_lines.num_lines():
1894 next_line = raw[line_number + 1] 1890 next_line = raw[line_number + 1]
1895 if next_line and match(r'\s*}', next_line) and 'namespace' not in ne xt_line and '} else ' not in next_line: 1891 if next_line and match(r'\s*}', next_line) and 'namespace' not in ne xt_line and '} else ' not in next_line:
1896 error(line_number, 'whitespace/blank_line', 3, 1892 error(line_number, 'whitespace/blank_line', 3,
1897 'Blank line at the end of a code block. Is this needed?') 1893 'Blank line at the end of a code block. Is this needed?')
1898 1894
1899 # Next, we check for proper spacing with respect to comments.
1900 comment_position = line.find('//')
1901 if comment_position != -1:
1902 # Check if the // may be in quotes. If so, ignore it
1903 # Comparisons made explicit for clarity
1904 if (line.count('"', 0, comment_position) - line.count('\\"', 0, comment_ position)) % 2 == 0: # not in quotes
1905 # Allow one space before end of line comment.
1906 if (not match(r'^\s*$', line[:comment_position])
1907 and (comment_position >= 1
1908 and ((line[comment_position - 1] not in string.whitespace)
1909 or (comment_position >= 2
1910 and line[comment_position - 2] in string.whitespac e)))):
1911 error(line_number, 'whitespace/comments', 5,
1912 'One space before end of line comments')
1913 # There should always be a space between the // and the comment
1914 commentend = comment_position + 2
1915 if commentend < len(line) and not line[commentend] == ' ':
1916 # but some lines are exceptions -- e.g. if they're big
1917 # comment delimiters like:
1918 # //----------------------------------------------------------
1919 # or they begin with multiple slashes followed by a space:
1920 # //////// Header comment
1921 matched = (search(r'[=/-]{4,}\s*$', line[commentend:])
1922 or search(r'^/+ ', line[commentend:]))
1923 if not matched:
1924 error(line_number, 'whitespace/comments', 4,
1925 'Should have a space between // and comment')
1926
1927 line = clean_lines.elided[line_number] # get rid of comments and strings 1895 line = clean_lines.elided[line_number] # get rid of comments and strings
1928 1896
1929 # Don't try to do spacing checks for operator methods 1897 # Don't try to do spacing checks for operator methods
1930 line = sub(r'operator(==|!=|<|<<|<=|>=|>>|>|\+=|-=|\*=|/=|%=|&=|\|=|^=|<<=|> >=|/)\(', 'operator\(', line) 1898 line = sub(r'operator(==|!=|<|<<|<=|>=|>>|>|\+=|-=|\*=|/=|%=|&=|\|=|^=|<<=|> >=|/)\(', 'operator\(', line)
1931 # Don't try to do spacing checks for #include or #import statements at 1899 # Don't try to do spacing checks for #include or #import statements at
1932 # minimum because it messes up checks for spacing around / 1900 # minimum because it messes up checks for spacing around /
1933 if match(r'\s*#\s*(?:include|import)', line): 1901 if match(r'\s*#\s*(?:include|import)', line):
1934 return 1902 return
1935 if search(r'[\w.]=[\w.]', line): 1903 if search(r'[\w.]=[\w.]', line):
1936 error(line_number, 'whitespace/operators', 4, 1904 error(line_number, 'whitespace/operators', 4,
1937 'Missing spaces around =') 1905 'Missing spaces around =')
danakj 2016/09/29 20:54:04 ..and fix these.. I'm inclined to suggest removi
1938 1906
1939 # FIXME: It's not ok to have spaces around binary operators like .
1940
1941 # You should always have whitespace around binary operators.
1942 # Alas, we can't test < or > because they're legitimately used sans spaces
1943 # (a->b, vector<int> a). The only time we can tell is a < with no >, and
1944 # only if it's not template params list spilling into the next line.
1945 matched = search(r'[^<>=!\s](==|!=|\+=|-=|\*=|/=|/|\|=|&=|<<=|>>=|<=|>=|\|\| |\||<<)[^<>=!\s]', line)
1946 if not matched:
1947 # Note that while it seems that the '<[^<]*' term in the following
1948 # regexp could be simplified to '<.*', which would indeed match
1949 # the same class of strings, the [^<] means that searching for the
1950 # regexp takes linear rather than quadratic time.
1951 if not search(r'<[^<]*,\s*$', line): # template params spill
1952 matched = search(r'[^<>=!\s](<)[^<>=!\s]([^>]|->)*$', line)
1953 if not matched:
1954 # Regardless of template arguments or operator>>, \w should not
1955 # follow >>.
1956 matched = search(r'(>>)\w', line)
1957 # If the line has no template arguments, >> is operator>>.
1958 # FIXME: This doesn't handle line-breaks inside template arguments.
1959 if not matched and not search(r'<', line):
1960 matched = search(r'\w(>>)', line)
1961
1962 if matched:
1963 error(line_number, 'whitespace/operators', 3,
1964 'Missing spaces around %s' % matched.group(1))
1965
1966 # There shouldn't be space around unary operators 1907 # There shouldn't be space around unary operators
1967 matched = search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line) 1908 matched = search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
1968 if matched: 1909 if matched:
1969 error(line_number, 'whitespace/operators', 4, 1910 error(line_number, 'whitespace/operators', 4,
1970 'Extra space for operator %s' % matched.group(1)) 1911 'Extra space for operator %s' % matched.group(1))
1971 1912
1972 # A pet peeve of mine: no spaces after an if, while, switch, or for 1913 # A pet peeve of mine: no spaces after an if, while, switch, or for
1973 matched = search(r' (if\(|for\(|foreach\(|while\(|switch\()', line) 1914 matched = search(r' (if\(|for\(|foreach\(|while\(|switch\()', line)
1974 if matched: 1915 if matched:
1975 error(line_number, 'whitespace/parens', 5, 1916 error(line_number, 'whitespace/parens', 5,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2027 elif file_extension == 'c': 1968 elif file_extension == 'c':
2028 # C Pointer declaration should have the * beside the variable not the ty pe name. 1969 # C Pointer declaration should have the * beside the variable not the ty pe name.
2029 matched = search(r'^\s*\w+\*\s+\w+', line) 1970 matched = search(r'^\s*\w+\*\s+\w+', line)
2030 if matched: 1971 if matched:
2031 error(line_number, 'whitespace/declaration', 3, 1972 error(line_number, 'whitespace/declaration', 3,
2032 'Declaration has space between * and variable name in %s' % ma tched.group(0).strip()) 1973 'Declaration has space between * and variable name in %s' % ma tched.group(0).strip())
2033 1974
2034 # Next we will look for issues with function calls. 1975 # Next we will look for issues with function calls.
2035 check_spacing_for_function_call(line, line_number, error) 1976 check_spacing_for_function_call(line, line_number, error)
2036 1977
2037 # Except after an opening paren, you should have spaces before your braces.
2038 # And since you should never have braces at the beginning of a line, this is
2039 # an easy test.
2040 if search(r'[^ ({]{', line):
2041 error(line_number, 'whitespace/braces', 5,
2042 'Missing space before {')
2043
2044 # Make sure '} else {' has spaces. 1978 # Make sure '} else {' has spaces.
2045 if search(r'}else', line): 1979 if search(r'}else', line):
2046 error(line_number, 'whitespace/braces', 5, 1980 error(line_number, 'whitespace/braces', 5,
2047 'Missing space before else') 1981 'Missing space before else')
2048 1982
2049 # You shouldn't have spaces before your brackets, except maybe after 1983 # You shouldn't have spaces before your brackets, except maybe after
2050 # 'delete []' or 'new char * []'. 1984 # 'delete []' or 'new char * []'.
2051 if search(r'\w\s+\[', line) and not search(r'delete\s+\[', line): 1985 if search(r'\w\s+\[', line) and not search(r'delete\s+\[', line):
2052 error(line_number, 'whitespace/braces', 5, 1986 error(line_number, 'whitespace/braces', 5,
2053 'Extra space before [') 1987 'Extra space before [')
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2127 'namespace should never be indented.') 2061 'namespace should never be indented.')
2128 return 2062 return
2129 looking_for_semicolon = False 2063 looking_for_semicolon = False
2130 line_offset = 0 2064 line_offset = 0
2131 in_preprocessor_directive = False 2065 in_preprocessor_directive = False
2132 for current_line in clean_lines.elided[line_number + 1:]: 2066 for current_line in clean_lines.elided[line_number + 1:]:
2133 line_offset += 1 2067 line_offset += 1
2134 if not current_line.strip(): 2068 if not current_line.strip():
2135 continue 2069 continue
2136 if not current_indentation_level: 2070 if not current_indentation_level:
2137 if not (in_preprocessor_directive or looking_for_semicolon):
2138 if not match(r'\S', current_line) and not file_state.did_inside_ namespace_indent_warning():
2139 file_state.set_did_inside_namespace_indent_warning()
2140 error(line_number + line_offset, 'whitespace/indent', 4,
2141 'Code inside a namespace should not be indented.')
2142 if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax. 2071 if in_preprocessor_directive or (current_line.strip()[0] == '#'): # This takes care of preprocessor directive syntax.
2143 in_preprocessor_directive = current_line[-1] == '\\' 2072 in_preprocessor_directive = current_line[-1] == '\\'
2144 else: 2073 else:
2145 looking_for_semicolon = ((';' not in current_line) and (current_ line.strip() 2074 looking_for_semicolon = ((';' not in current_line) and (current_ line.strip()
2146 [-1] != '}')) or (current_line[-1] == '\\') 2075 [-1] != '}')) or (current_line[-1] == '\\')
2147 else: 2076 else:
2148 looking_for_semicolon = False # If we have a brace we may not need a semicolon. 2077 looking_for_semicolon = False # If we have a brace we may not need a semicolon.
2149 current_indentation_level += current_line.count('{') - current_line.coun t('}') 2078 current_indentation_level += current_line.count('{') - current_line.coun t('}')
2150 if current_indentation_level < 0: 2079 if current_indentation_level < 0:
2151 break 2080 break
2152 2081
2153 2082
2154 def check_enum_casing(clean_lines, line_number, enum_state, error): 2083 def check_enum_casing(clean_lines, line_number, enum_state, error):
2155 """Looks for incorrectly named enum values. 2084 """Looks for incorrectly named enum values.
2156 2085
2157 Args: 2086 Args:
2158 clean_lines: A CleansedLines instance containing the file. 2087 clean_lines: A CleansedLines instance containing the file.
2159 line_number: The number of the line to check. 2088 line_number: The number of the line to check.
2160 enum_state: A _EnumState instance which maintains enum declaration state. 2089 enum_state: A _EnumState instance which maintains enum declaration state.
2161 error: The function to call with any errors found. 2090 error: The function to call with any errors found.
2162 """ 2091 """
2163 2092
2164 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2093 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2165 if not enum_state.process_clean_line(line): 2094 if not enum_state.process_clean_line(line):
2166 error(line_number, 'readability/enum_casing', 4, 2095 error(line_number, 'readability/enum_casing', 4,
2167 'enum members should use InterCaps with an initial capital letter. ') 2096 'enum members should use InterCaps with an initial capital letter. ')
2168 2097
2169 2098
2170 def check_directive_indentation(clean_lines, line_number, file_state, error):
2171 """Looks for indentation of preprocessor directives.
2172
2173 Args:
2174 clean_lines: A CleansedLines instance containing the file.
2175 line_number: The number of the line to check.
2176 file_state: A _FileState instance which maintains information about
2177 the state of things in the file.
2178 error: The function to call with any errors found.
2179 """
2180
2181 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2182
2183 indented_preprocessor_directives = match(r'\s+#', line)
2184 if not indented_preprocessor_directives:
2185 return
2186
2187 error(line_number, 'whitespace/indent', 4, 'preprocessor directives (e.g., # ifdef, #define, #import) should never be indented.')
2188
2189
2190 def get_initial_spaces_for_line(clean_line): 2099 def get_initial_spaces_for_line(clean_line):
2191 initial_spaces = 0 2100 initial_spaces = 0
2192 while initial_spaces < len(clean_line) and clean_line[initial_spaces] == ' ' : 2101 while initial_spaces < len(clean_line) and clean_line[initial_spaces] == ' ' :
2193 initial_spaces += 1 2102 initial_spaces += 1
2194 return initial_spaces 2103 return initial_spaces
2195 2104
2196 2105
2197 def check_indentation_amount(clean_lines, line_number, error):
2198 line = clean_lines.elided[line_number]
2199 initial_spaces = get_initial_spaces_for_line(line)
2200
2201 if initial_spaces % 4:
2202 error(line_number, 'whitespace/indent', 3,
2203 'Weird number of spaces at line-start. Are you using a 4-space in dent?')
2204 return
2205
2206 previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
2207 if not previous_line.strip() or match(r'\s*\w+\s*:\s*$', previous_line) or p revious_line[0] == '#':
2208 return
2209
2210 previous_line_initial_spaces = get_initial_spaces_for_line(previous_line)
2211 if initial_spaces > previous_line_initial_spaces + 4:
2212 error(line_number, 'whitespace/indent', 3, 'When wrapping a line, only i ndent 4 spaces.')
2213
2214
2215 def check_using_std(clean_lines, line_number, file_state, error): 2106 def check_using_std(clean_lines, line_number, file_state, error):
2216 """Looks for 'using std::foo;' statements which should be replaced with 'usi ng namespace std;'. 2107 """Looks for 'using std::foo;' statements which should be replaced with 'usi ng namespace std;'.
2217 2108
2218 Args: 2109 Args:
2219 clean_lines: A CleansedLines instance containing the file. 2110 clean_lines: A CleansedLines instance containing the file.
2220 line_number: The number of the line to check. 2111 line_number: The number of the line to check.
2221 file_state: A _FileState instance which maintains information about 2112 file_state: A _FileState instance which maintains information about
2222 the state of things in the file. 2113 the state of things in the file.
2223 error: The function to call with any errors found. 2114 error: The function to call with any errors found.
2224 """ 2115 """
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 2199
2309 switch_match = match(r'(?P<switch_indentation>\s*)switch\s*\(.+\)\s*{\s*$', line) 2200 switch_match = match(r'(?P<switch_indentation>\s*)switch\s*\(.+\)\s*{\s*$', line)
2310 if not switch_match: 2201 if not switch_match:
2311 return 2202 return
2312 2203
2313 switch_indentation = switch_match.group('switch_indentation') 2204 switch_indentation = switch_match.group('switch_indentation')
2314 inner_indentation = switch_indentation + ' ' * 4 2205 inner_indentation = switch_indentation + ' ' * 4
2315 line_offset = 0 2206 line_offset = 0
2316 encountered_nested_switch = False 2207 encountered_nested_switch = False
2317 2208
2318 for current_line in clean_lines.elided[line_number + 1:]: 2209 for current_line in clean_lines.elided[line_number + 1:]:
danakj 2016/09/29 20:54:04 This whole loop has no errors left so it could all
dcheng 2016/09/29 21:10:58 Done.
2319 line_offset += 1 2210 line_offset += 1
2320 2211
2321 # Skip not only empty lines but also those with preprocessor directives. 2212 # Skip not only empty lines but also those with preprocessor directives.
2322 if current_line.strip() == '' or current_line.startswith('#'): 2213 if current_line.strip() == '' or current_line.startswith('#'):
2323 continue 2214 continue
2324 2215
2325 if match(r'\s*switch\s*\(.+\)\s*{\s*$', current_line): 2216 if match(r'\s*switch\s*\(.+\)\s*{\s*$', current_line):
2326 # Complexity alarm - another switch statement nested inside the one 2217 # Complexity alarm - another switch statement nested inside the one
2327 # that we're currently testing. We'll need to track the extent of 2218 # that we're currently testing. We'll need to track the extent of
2328 # that inner switch if the upcoming label tests are still supposed 2219 # that inner switch if the upcoming label tests are still supposed
2329 # to work correctly. Let's not do that; instead, we'll finish 2220 # to work correctly. Let's not do that; instead, we'll finish
2330 # checking this line, and then leave it like that. Assuming the 2221 # checking this line, and then leave it like that. Assuming the
2331 # indentation is done consistently (even if incorrectly), this will 2222 # indentation is done consistently (even if incorrectly), this will
2332 # still catch all indentation issues in practice. 2223 # still catch all indentation issues in practice.
2333 encountered_nested_switch = True 2224 encountered_nested_switch = True
2334 2225
2335 current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_li ne>.*)$', current_line) 2226 current_indentation_match = match(r'(?P<indentation>\s*)(?P<remaining_li ne>.*)$', current_line)
2336 current_indentation = current_indentation_match.group('indentation') 2227 current_indentation = current_indentation_match.group('indentation')
2337 remaining_line = current_indentation_match.group('remaining_line') 2228 remaining_line = current_indentation_match.group('remaining_line')
2338 2229
2339 # End the check at the end of the switch statement. 2230 # End the check at the end of the switch statement.
2340 if remaining_line.startswith('}') and current_indentation == switch_inde ntation: 2231 if remaining_line.startswith('}') and current_indentation == switch_inde ntation:
2341 break 2232 break
2342 # Case and default branches should not be indented. The regexp also
2343 # catches single-line cases like "default: break;" but does not trigger
2344 # on stuff like "Document::Foo();".
2345 elif match(r'(default|case\s+.*)\s*:([^:].*)?$', remaining_line):
2346 if current_indentation != switch_indentation:
2347 error(line_number + line_offset, 'whitespace/indent', 4,
2348 'A case label should not be indented, but line up with its switch statement.')
2349 # Don't throw an error for multiple badly indented labels,
2350 # one should be enough to figure out the problem.
2351 break
2352 # We ignore goto labels at the very beginning of a line. 2233 # We ignore goto labels at the very beginning of a line.
2353 elif match(r'\w+\s*:\s*$', remaining_line): 2234 elif match(r'\w+\s*:\s*$', remaining_line):
2354 continue 2235 continue
2355 # It's not a goto label, so check if it's indented at least as far as
2356 # the switch statement plus one more level of indentation.
2357 elif not current_indentation.startswith(inner_indentation):
2358 error(line_number + line_offset, 'whitespace/indent', 4,
2359 'Non-label code inside switch statements should be indented.')
2360 # Don't throw an error for multiple badly indented statements,
2361 # one should be enough to figure out the problem.
2362 break
2363 2236
2364 if encountered_nested_switch: 2237 if encountered_nested_switch:
2365 break 2238 break
2366 2239
2367 2240
2368 def check_braces(clean_lines, line_number, error): 2241 def check_braces(clean_lines, line_number, error):
2369 """Looks for misplaced braces (e.g. at the end of line). 2242 """Looks for misplaced braces (e.g. at the end of line).
2370 2243
2371 Args: 2244 Args:
2372 clean_lines: A CleansedLines instance containing the file. 2245 clean_lines: A CleansedLines instance containing the file.
2373 line_number: The number of the line to check. 2246 line_number: The number of the line to check.
2374 error: The function to call with any errors found. 2247 error: The function to call with any errors found.
2375 """ 2248 """
2376 2249
2377 line = clean_lines.elided[line_number] # Get rid of comments and strings. 2250 line = clean_lines.elided[line_number] # Get rid of comments and strings.
2378 2251
2379 if match(r'\s*{\s*$', line):
2380 # We allow an open brace to start a line in the case where someone
2381 # is using braces for function definition or in a block to
2382 # explicitly create a new scope, which is commonly used to control
2383 # the lifetime of stack-allocated variables. We don't detect this
2384 # perfectly: we just don't complain if the last non-whitespace
2385 # character on the previous non-blank line is ';', ':', '{', '}',
2386 # ')' or is like a function declaration, and doesn't begin with
2387 # 'if|for|while|switch|else' without a beginning '{'.
2388 # We also allow '#' for #endif and '=' for array initialization.
2389 previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
2390 if ((not search(r'[;:}{)=]\s*$|\)\s*((const|override|final)\s*)*\s*(->\s *.+)?$', previous_line)
2391 or search(r'^\s*\b(if|for|foreach|while|switch|else)\b.*[^{]\s*$', previous_line))
2392 and previous_line.find('#') < 0):
2393 error(line_number, 'whitespace/braces', 4,
2394 'This { should be at the end of the previous line')
2395 elif (search(r'\)\s*(((const|override|final)\s*)*\s*)?{\s*$', line)
2396 and line.count('(') == line.count(')')
2397 and not search(r'\b(if|for|foreach|while|switch)\b', line)
2398 and not match(r'\s+[A-Z_][A-Z_0-9]+\b', line)):
2399 error(line_number, 'whitespace/braces', 4,
2400 'Place brace on its own line for function definitions.')
2401
2402 # An else clause should be on the same line as the preceding closing brace.
2403 if match(r'\s*else\s*', line):
2404 previous_line = get_previous_non_blank_line(clean_lines, line_number)[0]
2405 if match(r'\s*}\s*$', previous_line):
2406 error(line_number, 'whitespace/newline', 4,
2407 'An else should appear on the same line as the preceding }')
2408
2409 # Likewise, an else should never have the else clause on the same line
2410 if search(r'\belse [^\s{]', line) and not search(r'\belse if\b', line):
2411 error(line_number, 'whitespace/newline', 4,
2412 'Else clause should never be on same line as else (use 2 lines)')
2413
2414 # In the same way, a do/while should never be on one line
2415 if match(r'\s*do [^\s{]', line):
2416 error(line_number, 'whitespace/newline', 4,
2417 'do/while clauses should not be on a single line')
2418
2419 # Braces shouldn't be followed by a ; unless they're defining a struct 2252 # Braces shouldn't be followed by a ; unless they're defining a struct
2420 # or initializing an array. 2253 # or initializing an array.
2421 # We can't tell in general, but we can for some common cases. 2254 # We can't tell in general, but we can for some common cases.
2422 previous_line_number = line_number 2255 previous_line_number = line_number
2423 while True: 2256 while True:
2424 (previous_line, previous_line_number) = get_previous_non_blank_line(clea n_lines, previous_line_number) 2257 (previous_line, previous_line_number) = get_previous_non_blank_line(clea n_lines, previous_line_number)
2425 if match(r'\s+{.*}\s*;', line) and not previous_line.count(';'): 2258 if match(r'\s+{.*}\s*;', line) and not previous_line.count(';'):
2426 line = previous_line + line 2259 line = previous_line + line
2427 else: 2260 else:
2428 break 2261 break
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
2915 2748
2916 if '\t' in line: 2749 if '\t' in line:
2917 error(line_number, 'whitespace/tab', 1, 2750 error(line_number, 'whitespace/tab', 1,
2918 'Tab found; better to use spaces') 2751 'Tab found; better to use spaces')
2919 2752
2920 cleansed_line = clean_lines.elided[line_number] 2753 cleansed_line = clean_lines.elided[line_number]
2921 if line and line[-1].isspace(): 2754 if line and line[-1].isspace():
2922 error(line_number, 'whitespace/end_of_line', 4, 2755 error(line_number, 'whitespace/end_of_line', 4,
2923 'Line ends in whitespace. Consider deleting these extra spaces.') 2756 'Line ends in whitespace. Consider deleting these extra spaces.')
2924 2757
2925 if (cleansed_line.count(';') > 1
2926 # for loops are allowed two ;'s (and may run over two lines).
2927 and 'for' not in cleansed_line
2928 and (get_previous_non_blank_line(clean_lines, line_number)[0].find('for' ) == -1
2929 or get_previous_non_blank_line(clean_lines, line_number)[0].find('; ') != -1)
2930 # It's ok to have many commands in a switch case that fits in 1 line
2931 and not (('case ' in cleansed_line
2932 or 'default:' in cleansed_line)
2933 and 'break;' in cleansed_line)
2934 # Also it's ok to have many commands in trivial single-line accessors in class definitions.
2935 and not (match(r'.*\(.*\).*{.*.}', line)
2936 and class_state.classinfo_stack
2937 and line.count('{') == line.count('}'))
2938 and not cleansed_line.startswith('#define ')
2939 # It's ok to use use WTF_MAKE_NONCOPYABLE and WTF_MAKE_FAST_ALLOCATED ma cros in 1 line
2940 and not (cleansed_line.find("WTF_MAKE_NONCOPYABLE") != -1
2941 and cleansed_line.find("WTF_MAKE_FAST_ALLOCATED") != -1)):
2942 error(line_number, 'whitespace/newline', 4,
2943 'More than one command on the same line')
2944
2945 if cleansed_line.strip().endswith('||') or cleansed_line.strip().endswith('& &'):
2946 error(line_number, 'whitespace/operators', 4,
2947 'Boolean expressions that span multiple lines should have their '
2948 'operators on the left side of the line instead of the right side. ')
2949
2950 # Some more style checks 2758 # Some more style checks
2951 check_namespace_indentation(clean_lines, line_number, file_extension, file_s tate, error) 2759 check_namespace_indentation(clean_lines, line_number, file_extension, file_s tate, error)
2952 check_directive_indentation(clean_lines, line_number, file_state, error)
2953 check_using_std(clean_lines, line_number, file_state, error) 2760 check_using_std(clean_lines, line_number, file_state, error)
2954 check_max_min_macros(clean_lines, line_number, file_state, error) 2761 check_max_min_macros(clean_lines, line_number, file_state, error)
2955 check_ctype_functions(clean_lines, line_number, file_state, error) 2762 check_ctype_functions(clean_lines, line_number, file_state, error)
2956 check_switch_indentation(clean_lines, line_number, error) 2763 check_switch_indentation(clean_lines, line_number, error)
2957 check_braces(clean_lines, line_number, error) 2764 check_braces(clean_lines, line_number, error)
2958 check_exit_statement_simplifications(clean_lines, line_number, error) 2765 check_exit_statement_simplifications(clean_lines, line_number, error)
2959 check_spacing(file_extension, clean_lines, line_number, error) 2766 check_spacing(file_extension, clean_lines, line_number, error)
2960 check_check(clean_lines, line_number, error) 2767 check_check(clean_lines, line_number, error)
2961 check_deprecated_macros(clean_lines, line_number, error) 2768 check_deprecated_macros(clean_lines, line_number, error)
2962 check_for_comparisons_to_boolean(clean_lines, line_number, error) 2769 check_for_comparisons_to_boolean(clean_lines, line_number, error)
2963 check_for_null(clean_lines, line_number, file_state, error) 2770 check_for_null(clean_lines, line_number, file_state, error)
2964 check_indentation_amount(clean_lines, line_number, error)
2965 check_enum_casing(clean_lines, line_number, enum_state, error) 2771 check_enum_casing(clean_lines, line_number, enum_state, error)
2966 2772
2967 2773
2968 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') 2774 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
2969 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') 2775 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
2970 # Matches the first component of a filename delimited by -s and _s. That is: 2776 # Matches the first component of a filename delimited by -s and _s. That is:
2971 # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' 2777 # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
2972 # _RE_FIRST_COMPONENT.match('foo.cpp').group(0) == 'foo' 2778 # _RE_FIRST_COMPONENT.match('foo.cpp').group(0) == 'foo'
2973 # _RE_FIRST_COMPONENT.match('foo-bar_baz.cpp').group(0) == 'foo' 2779 # _RE_FIRST_COMPONENT.match('foo-bar_baz.cpp').group(0) == 'foo'
2974 # _RE_FIRST_COMPONENT.match('foo_bar-baz.cpp').group(0) == 'foo' 2780 # _RE_FIRST_COMPONENT.match('foo_bar-baz.cpp').group(0) == 'foo'
(...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after
4115 'runtime/references', 3921 'runtime/references',
4116 'runtime/rtti', 3922 'runtime/rtti',
4117 'runtime/sizeof', 3923 'runtime/sizeof',
4118 'runtime/string', 3924 'runtime/string',
4119 'runtime/threadsafe_fn', 3925 'runtime/threadsafe_fn',
4120 'runtime/unsigned', 3926 'runtime/unsigned',
4121 'runtime/virtual', 3927 'runtime/virtual',
4122 'whitespace/blank_line', 3928 'whitespace/blank_line',
4123 'whitespace/braces', 3929 'whitespace/braces',
4124 'whitespace/comma', 3930 'whitespace/comma',
4125 'whitespace/comments',
4126 'whitespace/declaration', 3931 'whitespace/declaration',
4127 'whitespace/end_of_line', 3932 'whitespace/end_of_line',
4128 'whitespace/ending_newline', 3933 'whitespace/ending_newline',
4129 'whitespace/indent', 3934 'whitespace/indent',
4130 'whitespace/line_length', 3935 'whitespace/line_length',
4131 'whitespace/newline',
4132 'whitespace/operators', 3936 'whitespace/operators',
4133 'whitespace/parens', 3937 'whitespace/parens',
4134 'whitespace/semicolon', 3938 'whitespace/semicolon',
4135 'whitespace/tab', 3939 'whitespace/tab',
4136 'whitespace/todo', 3940 'whitespace/todo',
4137 ]) 3941 ])
4138 3942
4139 fs = None 3943 fs = None
4140 3944
4141 def __init__(self, file_path, file_extension, handle_style_error, 3945 def __init__(self, file_path, file_extension, handle_style_error,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4173 3977
4174 def check(self, lines): 3978 def check(self, lines):
4175 _process_lines(self.file_path, self.file_extension, lines, 3979 _process_lines(self.file_path, self.file_extension, lines,
4176 self.handle_style_error, self.min_confidence) 3980 self.handle_style_error, self.min_confidence)
4177 3981
4178 3982
4179 # FIXME: Remove this function (requires refactoring unit tests). 3983 # FIXME: Remove this function (requires refactoring unit tests).
4180 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None): 3984 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None):
4181 checker = CppChecker(filename, file_extension, error, min_confidence, fs) 3985 checker = CppChecker(filename, file_extension, error, min_confidence, fs)
4182 checker.check(lines) 3986 checker.check(lines)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698