Code Duplication    Length = 145-145 lines in 2 locations

sdk/build-support/cpplint.py 1 location

@@ 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):

core/build-support/cpplint.py 1 location

@@ 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):