OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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) |
OLD | NEW |