Checks the use of CHECK and EXPECT macros. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found.
(filename, clean_lines, linenum, error)
| 5298 | |
| 5299 | |
| 5300 | def CheckCheck(filename, clean_lines, linenum, error): |
| 5301 | """Checks the use of CHECK and EXPECT macros. |
| 5302 | |
| 5303 | Args: |
| 5304 | filename: The name of the current file. |
| 5305 | clean_lines: A CleansedLines instance containing the file. |
| 5306 | linenum: The number of the line to check. |
| 5307 | error: The function to call with any errors found. |
| 5308 | """ |
| 5309 | |
| 5310 | # Decide the set of replacement macros that should be suggested |
| 5311 | lines = clean_lines.elided |
| 5312 | (check_macro, start_pos) = FindCheckMacro(lines[linenum]) |
| 5313 | if not check_macro: |
| 5314 | return |
| 5315 | |
| 5316 | # Find end of the boolean expression by matching parentheses |
| 5317 | (last_line, end_line, end_pos) = CloseExpression(clean_lines, linenum, start_pos) |
| 5318 | if end_pos < 0: |
| 5319 | return |
| 5320 | |
| 5321 | # If the check macro is followed by something other than a |
| 5322 | # semicolon, assume users will log their own custom error messages |
| 5323 | # and don't suggest any replacements. |
| 5324 | if not re.match(r"\s*;", last_line[end_pos:]): |
| 5325 | return |
| 5326 | |
| 5327 | if linenum == end_line: |
| 5328 | expression = lines[linenum][start_pos + 1 : end_pos - 1] |
| 5329 | else: |
| 5330 | expression = lines[linenum][start_pos + 1 :] |
| 5331 | for i in range(linenum + 1, end_line): |
| 5332 | expression += lines[i] |
| 5333 | expression += last_line[0 : end_pos - 1] |
| 5334 | |
| 5335 | # Parse expression so that we can take parentheses into account. |
| 5336 | # This avoids false positives for inputs like "CHECK((a < 4) == b)", |
| 5337 | # which is not replaceable by CHECK_LE. |
| 5338 | lhs = "" |
| 5339 | rhs = "" |
| 5340 | operator = None |
| 5341 | while expression: |
| 5342 | matched = re.match( |
| 5343 | r"^\s*(<<|<<=|>>|>>=|->\*|->|&&|\|\||" |
| 5344 | r"==|!=|>=|>|<=|<|\()(.*)$", |
| 5345 | expression, |
| 5346 | ) |
| 5347 | if matched: |
| 5348 | token = matched.group(1) |
| 5349 | if token == "(": |
| 5350 | # Parenthesized operand |
| 5351 | expression = matched.group(2) |
| 5352 | (end, _) = FindEndOfExpressionInLine(expression, 0, ["("]) |
| 5353 | if end < 0: |
| 5354 | return # Unmatched parenthesis |
| 5355 | lhs += "(" + expression[0:end] |
| 5356 | expression = expression[end:] |
| 5357 | elif token in ("&&", "||"): |
no test coverage detected
searching dependent graphs…