| @@ 3995-4139 (lines=145) @@ | ||
| 3992 | 'If/else bodies with multiple statements require braces') |
|
| 3993 | ||
| 3994 | ||
| 3995 | def CheckTrailingSemicolon(filename, clean_lines, linenum, error): |
|
| 3996 | """Looks for redundant trailing semicolon. |
|
| 3997 | ||
| 3998 | Args: |
|
| 3999 | filename: The name of the current file. |
|
| 4000 | clean_lines: A CleansedLines instance containing the file. |
|
| 4001 | linenum: The number of the line to check. |
|
| 4002 | error: The function to call with any errors found. |
|
| 4003 | """ |
|
| 4004 | ||
| 4005 | line = clean_lines.elided[linenum] |
|
| 4006 | ||
| 4007 | # Block bodies should not be followed by a semicolon. Due to C++11 |
|
| 4008 | # brace initialization, there are more places where semicolons are |
|
| 4009 | # required than not, so we use a whitelist approach to check these |
|
| 4010 | # rather than a blacklist. These are the places where "};" should |
|
| 4011 | # be replaced by just "}": |
|
| 4012 | # 1. Some flavor of block following closing parenthesis: |
|
| 4013 | # for (;;) {}; |
|
| 4014 | # while (...) {}; |
|
| 4015 | # switch (...) {}; |
|
| 4016 | # Function(...) {}; |
|
| 4017 | # if (...) {}; |
|
| 4018 | # if (...) else if (...) {}; |
|
| 4019 | # |
|
| 4020 | # 2. else block: |
|
| 4021 | # if (...) else {}; |
|
| 4022 | # |
|
| 4023 | # 3. const member function: |
|
| 4024 | # Function(...) const {}; |
|
| 4025 | # |
|
| 4026 | # 4. Block following some statement: |
|
| 4027 | # x = 42; |
|
| 4028 | # {}; |
|
| 4029 | # |
|
| 4030 | # 5. Block at the beginning of a function: |
|
| 4031 | # Function(...) { |
|
| 4032 | # {}; |
|
| 4033 | # } |
|
| 4034 | # |
|
| 4035 | # Note that naively checking for the preceding "{" will also match |
|
| 4036 | # braces inside multi-dimensional arrays, but this is fine since |
|
| 4037 | # that expression will not contain semicolons. |
|
| 4038 | # |
|
| 4039 | # 6. Block following another block: |
|
| 4040 | # while (true) {} |
|
| 4041 | # {}; |
|
| 4042 | # |
|
| 4043 | # 7. End of namespaces: |
|
| 4044 | # namespace {}; |
|
| 4045 | # |
|
| 4046 | # These semicolons seems far more common than other kinds of |
|
| 4047 | # redundant semicolons, possibly due to people converting classes |
|
| 4048 | # to namespaces. For now we do not warn for this case. |
|
| 4049 | # |
|
| 4050 | # Try matching case 1 first. |
|
| 4051 | match = Match(r'^(.*\)\s*)\{', line) |
|
| 4052 | if match: |
|
| 4053 | # Matched closing parenthesis (case 1). Check the token before the |
|
| 4054 | # matching opening parenthesis, and don't warn if it looks like a |
|
| 4055 | # macro. This avoids these false positives: |
|
| 4056 | # - macro that defines a base class |
|
| 4057 | # - multi-line macro that defines a base class |
|
| 4058 | # - macro that defines the whole class-head |
|
| 4059 | # |
|
| 4060 | # But we still issue warnings for macros that we know are safe to |
|
| 4061 | # warn, specifically: |
|
| 4062 | # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P |
|
| 4063 | # - TYPED_TEST |
|
| 4064 | # - INTERFACE_DEF |
|
| 4065 | # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: |
|
| 4066 | # |
|
| 4067 | # We implement a whitelist of safe macros instead of a blacklist of |
|
| 4068 | # unsafe macros, even though the latter appears less frequently in |
|
| 4069 | # google code and would have been easier to implement. This is because |
|
| 4070 | # the downside for getting the whitelist wrong means some extra |
|
| 4071 | # semicolons, while the downside for getting the blacklist wrong |
|
| 4072 | # would result in compile errors. |
|
| 4073 | # |
|
| 4074 | # In addition to macros, we also don't want to warn on |
|
| 4075 | # - Compound literals |
|
| 4076 | # - Lambdas |
|
| 4077 | # - alignas specifier with anonymous structs |
|
| 4078 | # - decltype |
|
| 4079 | closing_brace_pos = match.group(1).rfind(')') |
|
| 4080 | opening_parenthesis = ReverseCloseExpression( |
|
| 4081 | clean_lines, linenum, closing_brace_pos) |
|
| 4082 | if opening_parenthesis[2] > -1: |
|
| 4083 | line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] |
|
| 4084 | macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix) |
|
| 4085 | func = Match(r'^(.*\])\s*$', line_prefix) |
|
| 4086 | if ((macro and |
|
| 4087 | macro.group(1) not in ( |
|
| 4088 | 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', |
|
| 4089 | 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', |
|
| 4090 | 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or |
|
| 4091 | (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or |
|
| 4092 | Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or |
|
| 4093 | Search(r'\bdecltype$', line_prefix) or |
|
| 4094 | Search(r'\s+=\s*$', line_prefix)): |
|
| 4095 | match = None |
|
| 4096 | if (match and |
|
| 4097 | opening_parenthesis[1] > 1 and |
|
| 4098 | Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): |
|
| 4099 | # Multi-line lambda-expression |
|
| 4100 | match = None |
|
| 4101 | ||
| 4102 | else: |
|
| 4103 | # Try matching cases 2-3. |
|
| 4104 | match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) |
|
| 4105 | if not match: |
|
| 4106 | # Try matching cases 4-6. These are always matched on separate lines. |
|
| 4107 | # |
|
| 4108 | # Note that we can't simply concatenate the previous line to the |
|
| 4109 | # current line and do a single match, otherwise we may output |
|
| 4110 | # duplicate warnings for the blank line case: |
|
| 4111 | # if (cond) { |
|
| 4112 | # // blank line |
|
| 4113 | # } |
|
| 4114 | prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] |
|
| 4115 | if prevline and Search(r'[;{}]\s*$', prevline): |
|
| 4116 | match = Match(r'^(\s*)\{', line) |
|
| 4117 | ||
| 4118 | # Check matching closing brace |
|
| 4119 | if match: |
|
| 4120 | (endline, endlinenum, endpos) = CloseExpression( |
|
| 4121 | clean_lines, linenum, len(match.group(1))) |
|
| 4122 | if endpos > -1 and Match(r'^\s*;', endline[endpos:]): |
|
| 4123 | # Current {} pair is eligible for semicolon check, and we have found |
|
| 4124 | # the redundant semicolon, output warning here. |
|
| 4125 | # |
|
| 4126 | # Note: because we are scanning forward for opening braces, and |
|
| 4127 | # outputting warnings for the matching closing brace, if there are |
|
| 4128 | # nested blocks with trailing semicolons, we will get the error |
|
| 4129 | # messages in reversed order. |
|
| 4130 | ||
| 4131 | # We need to check the line forward for NOLINT |
|
| 4132 | raw_lines = clean_lines.raw_lines |
|
| 4133 | ParseNolintSuppressions(filename, raw_lines[endlinenum-1], endlinenum-1, |
|
| 4134 | error) |
|
| 4135 | ParseNolintSuppressions(filename, raw_lines[endlinenum], endlinenum, |
|
| 4136 | error) |
|
| 4137 | ||
| 4138 | error(filename, endlinenum, 'readability/braces', 4, |
|
| 4139 | "You don't need a ; after a }") |
|
| 4140 | ||
| 4141 | ||
| 4142 | def CheckEmptyBlockBody(filename, clean_lines, linenum, error): |
|
| @@ 3995-4139 (lines=145) @@ | ||
| 3992 | 'If/else bodies with multiple statements require braces') |
|
| 3993 | ||
| 3994 | ||
| 3995 | def CheckTrailingSemicolon(filename, clean_lines, linenum, error): |
|
| 3996 | """Looks for redundant trailing semicolon. |
|
| 3997 | ||
| 3998 | Args: |
|
| 3999 | filename: The name of the current file. |
|
| 4000 | clean_lines: A CleansedLines instance containing the file. |
|
| 4001 | linenum: The number of the line to check. |
|
| 4002 | error: The function to call with any errors found. |
|
| 4003 | """ |
|
| 4004 | ||
| 4005 | line = clean_lines.elided[linenum] |
|
| 4006 | ||
| 4007 | # Block bodies should not be followed by a semicolon. Due to C++11 |
|
| 4008 | # brace initialization, there are more places where semicolons are |
|
| 4009 | # required than not, so we use a whitelist approach to check these |
|
| 4010 | # rather than a blacklist. These are the places where "};" should |
|
| 4011 | # be replaced by just "}": |
|
| 4012 | # 1. Some flavor of block following closing parenthesis: |
|
| 4013 | # for (;;) {}; |
|
| 4014 | # while (...) {}; |
|
| 4015 | # switch (...) {}; |
|
| 4016 | # Function(...) {}; |
|
| 4017 | # if (...) {}; |
|
| 4018 | # if (...) else if (...) {}; |
|
| 4019 | # |
|
| 4020 | # 2. else block: |
|
| 4021 | # if (...) else {}; |
|
| 4022 | # |
|
| 4023 | # 3. const member function: |
|
| 4024 | # Function(...) const {}; |
|
| 4025 | # |
|
| 4026 | # 4. Block following some statement: |
|
| 4027 | # x = 42; |
|
| 4028 | # {}; |
|
| 4029 | # |
|
| 4030 | # 5. Block at the beginning of a function: |
|
| 4031 | # Function(...) { |
|
| 4032 | # {}; |
|
| 4033 | # } |
|
| 4034 | # |
|
| 4035 | # Note that naively checking for the preceding "{" will also match |
|
| 4036 | # braces inside multi-dimensional arrays, but this is fine since |
|
| 4037 | # that expression will not contain semicolons. |
|
| 4038 | # |
|
| 4039 | # 6. Block following another block: |
|
| 4040 | # while (true) {} |
|
| 4041 | # {}; |
|
| 4042 | # |
|
| 4043 | # 7. End of namespaces: |
|
| 4044 | # namespace {}; |
|
| 4045 | # |
|
| 4046 | # These semicolons seems far more common than other kinds of |
|
| 4047 | # redundant semicolons, possibly due to people converting classes |
|
| 4048 | # to namespaces. For now we do not warn for this case. |
|
| 4049 | # |
|
| 4050 | # Try matching case 1 first. |
|
| 4051 | match = Match(r'^(.*\)\s*)\{', line) |
|
| 4052 | if match: |
|
| 4053 | # Matched closing parenthesis (case 1). Check the token before the |
|
| 4054 | # matching opening parenthesis, and don't warn if it looks like a |
|
| 4055 | # macro. This avoids these false positives: |
|
| 4056 | # - macro that defines a base class |
|
| 4057 | # - multi-line macro that defines a base class |
|
| 4058 | # - macro that defines the whole class-head |
|
| 4059 | # |
|
| 4060 | # But we still issue warnings for macros that we know are safe to |
|
| 4061 | # warn, specifically: |
|
| 4062 | # - TEST, TEST_F, TEST_P, MATCHER, MATCHER_P |
|
| 4063 | # - TYPED_TEST |
|
| 4064 | # - INTERFACE_DEF |
|
| 4065 | # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: |
|
| 4066 | # |
|
| 4067 | # We implement a whitelist of safe macros instead of a blacklist of |
|
| 4068 | # unsafe macros, even though the latter appears less frequently in |
|
| 4069 | # google code and would have been easier to implement. This is because |
|
| 4070 | # the downside for getting the whitelist wrong means some extra |
|
| 4071 | # semicolons, while the downside for getting the blacklist wrong |
|
| 4072 | # would result in compile errors. |
|
| 4073 | # |
|
| 4074 | # In addition to macros, we also don't want to warn on |
|
| 4075 | # - Compound literals |
|
| 4076 | # - Lambdas |
|
| 4077 | # - alignas specifier with anonymous structs |
|
| 4078 | # - decltype |
|
| 4079 | closing_brace_pos = match.group(1).rfind(')') |
|
| 4080 | opening_parenthesis = ReverseCloseExpression( |
|
| 4081 | clean_lines, linenum, closing_brace_pos) |
|
| 4082 | if opening_parenthesis[2] > -1: |
|
| 4083 | line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] |
|
| 4084 | macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix) |
|
| 4085 | func = Match(r'^(.*\])\s*$', line_prefix) |
|
| 4086 | if ((macro and |
|
| 4087 | macro.group(1) not in ( |
|
| 4088 | 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', |
|
| 4089 | 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', |
|
| 4090 | 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or |
|
| 4091 | (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or |
|
| 4092 | Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or |
|
| 4093 | Search(r'\bdecltype$', line_prefix) or |
|
| 4094 | Search(r'\s+=\s*$', line_prefix)): |
|
| 4095 | match = None |
|
| 4096 | if (match and |
|
| 4097 | opening_parenthesis[1] > 1 and |
|
| 4098 | Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): |
|
| 4099 | # Multi-line lambda-expression |
|
| 4100 | match = None |
|
| 4101 | ||
| 4102 | else: |
|
| 4103 | # Try matching cases 2-3. |
|
| 4104 | match = Match(r'^(.*(?:else|\)\s*const)\s*)\{', line) |
|
| 4105 | if not match: |
|
| 4106 | # Try matching cases 4-6. These are always matched on separate lines. |
|
| 4107 | # |
|
| 4108 | # Note that we can't simply concatenate the previous line to the |
|
| 4109 | # current line and do a single match, otherwise we may output |
|
| 4110 | # duplicate warnings for the blank line case: |
|
| 4111 | # if (cond) { |
|
| 4112 | # // blank line |
|
| 4113 | # } |
|
| 4114 | prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] |
|
| 4115 | if prevline and Search(r'[;{}]\s*$', prevline): |
|
| 4116 | match = Match(r'^(\s*)\{', line) |
|
| 4117 | ||
| 4118 | # Check matching closing brace |
|
| 4119 | if match: |
|
| 4120 | (endline, endlinenum, endpos) = CloseExpression( |
|
| 4121 | clean_lines, linenum, len(match.group(1))) |
|
| 4122 | if endpos > -1 and Match(r'^\s*;', endline[endpos:]): |
|
| 4123 | # Current {} pair is eligible for semicolon check, and we have found |
|
| 4124 | # the redundant semicolon, output warning here. |
|
| 4125 | # |
|
| 4126 | # Note: because we are scanning forward for opening braces, and |
|
| 4127 | # outputting warnings for the matching closing brace, if there are |
|
| 4128 | # nested blocks with trailing semicolons, we will get the error |
|
| 4129 | # messages in reversed order. |
|
| 4130 | ||
| 4131 | # We need to check the line forward for NOLINT |
|
| 4132 | raw_lines = clean_lines.raw_lines |
|
| 4133 | ParseNolintSuppressions(filename, raw_lines[endlinenum-1], endlinenum-1, |
|
| 4134 | error) |
|
| 4135 | ParseNolintSuppressions(filename, raw_lines[endlinenum], endlinenum, |
|
| 4136 | error) |
|
| 4137 | ||
| 4138 | error(filename, endlinenum, 'readability/braces', 4, |
|
| 4139 | "You don't need a ; after a }") |
|
| 4140 | ||
| 4141 | ||
| 4142 | def CheckEmptyBlockBody(filename, clean_lines, linenum, error): |
|