Chromium Code Reviews| 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 3393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3404 # We should continue checking if this is a function | 3404 # We should continue checking if this is a function |
| 3405 # declaration because we need to check its arguments. | 3405 # declaration because we need to check its arguments. |
| 3406 # Also, we need to check multiple declarations. | 3406 # Also, we need to check multiple declarations. |
| 3407 if character_after_identifier != '(' and character_after_identifier != ' ,': | 3407 if character_after_identifier != '(' and character_after_identifier != ' ,': |
| 3408 return | 3408 return |
| 3409 | 3409 |
| 3410 number_of_identifiers += 1 | 3410 number_of_identifiers += 1 |
| 3411 line = line[matched.end():] | 3411 line = line[matched.end():] |
| 3412 | 3412 |
| 3413 | 3413 |
| 3414 def check_for_toFoo_definition(filename, pattern, error): | 3414 def check_for_toFoo_definition(filename, search_func_name, grep_patterns, error) : |
|
aarya
2014/01/27 19:45:56
check_for_toFoo_definition -> check_for_cast_defin
r.kasibhatla
2014/02/03 15:29:15
Done.
| |
| 3415 """ Reports for using static_cast instead of toFoo convenience function. | 3415 """Checks for a Cpp-style static cast on objects by searching for the patter n. |
| 3416 | |
| 3417 This function will output warnings to make sure you are actually using | |
| 3418 the added toFoo conversion functions rather than directly hard coding | |
| 3419 the static_cast<Classname*> call. For example, you should toHTMLELement(Node *) | |
| 3420 to convert Node* to HTMLElement*, instead of static_cast<HTMLElement*>(Node* ) | |
| 3421 | 3416 |
| 3422 Args: | 3417 Args: |
| 3423 filename: The name of the header file in which to check for toFoo definiti on. | 3418 filename: The name of the header file in which to check for toFoo definiti on. |
| 3424 pattern: The conversion function pattern to grep for. | 3419 search_func_name: The toFoo convinience function string. |
|
Dirk Pranke
2014/01/27 19:38:51
Nit: "convenience".
aarya
2014/01/27 19:45:56
typo: convenience
r.kasibhatla
2014/02/03 15:29:15
Done.
r.kasibhatla
2014/02/03 15:29:15
Done.
| |
| 3420 grep_patterns: Array consisting the regex patterns to search for. | |
| 3425 error: The function to call with any errors found. | 3421 error: The function to call with any errors found. |
| 3426 """ | 3422 """ |
| 3427 def get_abs_filepath(filename): | 3423 def get_abs_filepath(filename): |
| 3428 fileSystem = FileSystem() | 3424 fileSystem = FileSystem() |
| 3429 base_dir = fileSystem.path_to_module(FileSystem.__module__).split('WebKi t', 1)[0] | 3425 base_dir = fileSystem.path_to_module(FileSystem.__module__).split('WebKi t', 1)[0] |
| 3430 base_dir = ''.join((base_dir, 'WebKit/Source')) | 3426 base_dir = ''.join((base_dir, 'WebKit/Source')) |
| 3431 for root, dirs, names in os.walk(base_dir): | 3427 for root, dirs, names in os.walk(base_dir): |
| 3432 if filename in names: | 3428 if filename in names: |
| 3433 return os.path.join(root, filename) | 3429 return os.path.join(root, filename) |
| 3434 return None | 3430 return None |
| 3435 | 3431 |
| 3436 def grep(lines, pattern, error): | 3432 def grep(lines, search_func_name, grep_patterns, error): |
| 3437 matches = [] | 3433 matches = [] |
| 3438 function_state = None | 3434 function_state = None |
| 3439 for line_number in xrange(lines.num_lines()): | 3435 for line_number in xrange(lines.num_lines()): |
| 3440 line = (lines.elided[line_number]).rstrip() | 3436 line = (lines.elided[line_number]).rstrip() |
| 3441 try: | 3437 try: |
| 3442 if pattern in line: | 3438 # Search for DEFINE_TYPE_CASTS pattern in the file. |
| 3439 if re.search(grep_patterns[0], line): | |
|
aarya
2014/01/27 19:45:56
grep_patterns[0], grep_patterns[1] is not a good w
r.kasibhatla
2014/02/03 15:29:15
Done.
| |
| 3440 matches.append([line, line_number + 1, line_number + 1]) | |
| 3441 # DEFINE_TYPE_CASTS pattern not found. Search for toFoo pattern instead in the file. | |
|
Dirk Pranke
2014/01/27 19:38:51
Nit: it's a bit odd to me to have a comment immedi
r.kasibhatla
2014/02/03 15:29:15
Done.
| |
| 3442 elif re.search(grep_patterns[1], line): | |
| 3443 if not function_state: | 3443 if not function_state: |
| 3444 function_state = _FunctionState(1) | 3444 function_state = _FunctionState(1) |
| 3445 detect_functions(lines, line_number, function_state, error) | 3445 detect_functions(lines, line_number, function_state, error) |
| 3446 # Exclude the match of dummy conversion function. Dummy func tion is just to | 3446 # Exclude the match of dummy conversion function. Dummy func tion is just to |
| 3447 # catch invalid conversions and shouldn't be part of possibl e alternatives. | 3447 # catch invalid conversions and shouldn't be part of possibl e alternatives. |
| 3448 result = re.search(r'%s(\s+)%s' % ("void", pattern), line) | 3448 result = re.search(r'%s(\s+)%s' % ("void", search_func_name) , line) |
| 3449 if not result: | 3449 if not result: |
| 3450 matches.append([line, function_state.body_start_position .row, function_state.end_position.row + 1]) | 3450 matches.append([line, function_state.body_start_position .row, function_state.end_position.row + 1]) |
| 3451 function_state = None | 3451 function_state = None |
| 3452 except UnicodeDecodeError: | 3452 except UnicodeDecodeError: |
| 3453 # There would be no non-ascii characters in the codebase ever. T he only exception | 3453 # There would be no non-ascii characters in the codebase ever. T he only exception |
| 3454 # would be comments/copyright text which might have non-ascii ch aracters. Hence, | 3454 # would be comments/copyright text which might have non-ascii ch aracters. Hence, |
| 3455 # it is prefectly safe to catch the UnicodeDecodeError and just pass the line. | 3455 # it is prefectly safe to catch the UnicodeDecodeError and just pass the line. |
| 3456 pass | 3456 pass |
| 3457 | 3457 |
| 3458 return matches | 3458 return matches |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 3484 file_path = get_abs_filepath(filename) | 3484 file_path = get_abs_filepath(filename) |
| 3485 if not file_path: | 3485 if not file_path: |
| 3486 return None | 3486 return None |
| 3487 try: | 3487 try: |
| 3488 f = open(file_path) | 3488 f = open(file_path) |
| 3489 clean_lines = CleansedLines(f.readlines()) | 3489 clean_lines = CleansedLines(f.readlines()) |
| 3490 finally: | 3490 finally: |
| 3491 f.close() | 3491 f.close() |
| 3492 | 3492 |
| 3493 # Make a list of all genuine alternatives to static_cast. | 3493 # Make a list of all genuine alternatives to static_cast. |
| 3494 matches = grep(clean_lines, pattern, error) | 3494 matches = grep(clean_lines, search_func_name, grep_patterns, error) |
| 3495 return matches | 3495 return matches |
| 3496 | 3496 |
| 3497 | 3497 |
| 3498 def check_for_object_static_cast(processing_file, line_number, line, error): | 3498 def check_for_object_static_cast(processing_file, line_number, line, error): |
| 3499 """Checks for a Cpp-style static cast on objects by looking for the pattern. | 3499 """ Reports for using static_cast instead of toFoo convenience function. |
| 3500 | |
| 3501 This function will output warnings to make sure you are actually using | |
| 3502 the added toFoo conversion functions rather than directly hard coding | |
| 3503 the static_cast<Classname*> call. For example, you should toHTMLELement(Node *) | |
| 3504 to convert Node* to HTMLElement*, instead of static_cast<HTMLElement*>(Node* ) | |
| 3500 | 3505 |
| 3501 Args: | 3506 Args: |
| 3502 processing_file: The name of the processing file. | 3507 processing_file: The name of the processing file. |
| 3503 line_number: The number of the line to check. | 3508 line_number: The number of the line to check. |
| 3504 line: The line of code to check. | 3509 line: The line of code to check. |
| 3505 error: The function to call with any errors found. | 3510 error: The function to call with any errors found. |
| 3506 """ | 3511 """ |
| 3512 | |
| 3507 matched = search(r'\bstatic_cast<(\s*\w*:?:?\w+\s*\*+\s*)>', line) | 3513 matched = search(r'\bstatic_cast<(\s*\w*:?:?\w+\s*\*+\s*)>', line) |
| 3508 if not matched: | 3514 if not matched: |
| 3509 return | 3515 return |
| 3510 | 3516 |
| 3511 class_name = re.sub('[\*]', '', matched.group(1)) | 3517 class_name = re.sub('[\*]', '', matched.group(1)) |
| 3512 class_name = class_name.strip() | 3518 class_name = class_name.strip() |
| 3513 # Ignore (for now) when the casting is to void*, | 3519 # Ignore (for now) when the casting is to void*, |
| 3514 if class_name == 'void': | 3520 if class_name == 'void': |
| 3515 return | 3521 return |
| 3516 | 3522 |
| 3517 namespace_pos = class_name.find(':') | 3523 namespace_pos = class_name.find(':') |
| 3518 if not namespace_pos == -1: | 3524 if not namespace_pos == -1: |
| 3519 class_name = class_name[namespace_pos + 2:] | 3525 class_name = class_name[namespace_pos + 2:] |
| 3520 | 3526 |
| 3521 header_file = ''.join((class_name, '.h')) | 3527 header_file = ''.join((class_name, '.h')) |
| 3522 matches = check_for_toFoo_definition(header_file, ''.join(('to', class_name) ), error) | 3528 toFoo_name = ''.join(('to', class_name)) |
| 3523 # Ignore (for now) if not able to find the header where toFoo might be defin ed. | 3529 matching_patterns = [] |
| 3524 # TODO: Handle cases where Classname might be defined in some other header o r cpp file. | 3530 matching_patterns.append(re.compile(r'\s*DEFINE_(\w*)TYPE_CASTS\(%s,(.+)(\); $)' % class_name)) |
| 3531 matching_patterns.append(re.compile(r'[ \w]*%s\*\s+%s\((.+)\)$' % (class_nam e, toFoo_name))) | |
| 3532 | |
| 3533 matches = check_for_toFoo_definition(header_file, toFoo_name, matching_patte rns, error) | |
| 3534 # FIXME(kphanee): Handle cases where Classname might be defined in some othe r header or cpp file. | |
|
Dirk Pranke
2014/01/27 19:38:51
Nit: We don't use usernames in FIXMEs.
r.kasibhatla
2014/02/03 15:29:15
Done.
| |
| 3535 # It would remove this hack for ignoring not finding Foo.h | |
|
aarya
2014/01/27 19:45:56
This line is not clear, can you rephrase this.
r.kasibhatla
2014/02/03 15:29:15
Done.
| |
| 3525 if matches is None: | 3536 if matches is None: |
| 3526 return | 3537 return |
| 3527 | 3538 |
| 3528 report_error = True | 3539 report_error = True |
| 3529 # Ensure found static_cast instance is not from within toFoo definition itse lf. | 3540 # Ensure found static_cast instance is not from within toFoo definition itse lf. |
| 3530 if (os.path.basename(processing_file) == header_file): | 3541 if (os.path.basename(processing_file) == header_file): |
| 3531 for item in matches: | 3542 for item in matches: |
| 3532 if line_number in range(item[1], item[2]): | 3543 if line_number in range(item[1], item[2]): |
| 3533 report_error = False | 3544 report_error = False |
| 3534 break | 3545 break |
| 3535 | 3546 |
| 3536 if report_error: | 3547 if report_error: |
| 3537 if len(matches): | 3548 if len(matches): |
| 3538 # toFoo is defined - enforce using it. | 3549 # toFoo is defined - enforce using it. |
| 3539 # TODO: Suggest an appropriate toFoo from the alternatives present i n matches. | 3550 # TODO: Suggest an appropriate toFoo from the alternatives present i n matches. |
| 3540 error(line_number, 'runtime/casting', 4, | 3551 error(line_number, 'security/casting', 4, |
| 3541 'static_cast of class objects is not allowed. Use to%s defined in %s.' % | 3552 'static_cast of class objects is not allowed. Use to%s defined in %s.' % |
| 3542 (class_name, header_file)) | 3553 (class_name, header_file)) |
| 3543 else: | 3554 else: |
| 3544 # No toFoo defined - enforce definition & usage. | 3555 # No toFoo defined - enforce definition & usage. |
| 3545 # TODO: Automate the generation of toFoo() to avoid any slippages ev er. | 3556 # TODO: Automate the generation of toFoo() to avoid any slippages ev er. |
| 3546 error(line_number, 'runtime/casting', 4, | 3557 error(line_number, 'runtime/casting', 4, |
| 3547 'static_cast of class objects is not allowed. Add to%s in %s a nd use it instead.' % | 3558 'static_cast of class objects is not allowed. Add to%s in %s a nd use it instead.' % |
| 3548 (class_name, header_file)) | 3559 (class_name, header_file)) |
| 3549 | 3560 |
| 3550 | 3561 |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3977 'runtime/memset', | 3988 'runtime/memset', |
| 3978 'runtime/printf', | 3989 'runtime/printf', |
| 3979 'runtime/printf_format', | 3990 'runtime/printf_format', |
| 3980 'runtime/references', | 3991 'runtime/references', |
| 3981 'runtime/rtti', | 3992 'runtime/rtti', |
| 3982 'runtime/sizeof', | 3993 'runtime/sizeof', |
| 3983 'runtime/string', | 3994 'runtime/string', |
| 3984 'runtime/threadsafe_fn', | 3995 'runtime/threadsafe_fn', |
| 3985 'runtime/unsigned', | 3996 'runtime/unsigned', |
| 3986 'runtime/virtual', | 3997 'runtime/virtual', |
| 3998 'security/casting', | |
| 3987 'whitespace/blank_line', | 3999 'whitespace/blank_line', |
| 3988 'whitespace/braces', | 4000 'whitespace/braces', |
| 3989 'whitespace/comma', | 4001 'whitespace/comma', |
| 3990 'whitespace/comments', | 4002 'whitespace/comments', |
| 3991 'whitespace/declaration', | 4003 'whitespace/declaration', |
| 3992 'whitespace/end_of_line', | 4004 'whitespace/end_of_line', |
| 3993 'whitespace/ending_newline', | 4005 'whitespace/ending_newline', |
| 3994 'whitespace/indent', | 4006 'whitespace/indent', |
| 3995 'whitespace/line_length', | 4007 'whitespace/line_length', |
| 3996 'whitespace/newline', | 4008 'whitespace/newline', |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4039 | 4051 |
| 4040 def check(self, lines): | 4052 def check(self, lines): |
| 4041 _process_lines(self.file_path, self.file_extension, lines, | 4053 _process_lines(self.file_path, self.file_extension, lines, |
| 4042 self.handle_style_error, self.min_confidence) | 4054 self.handle_style_error, self.min_confidence) |
| 4043 | 4055 |
| 4044 | 4056 |
| 4045 # FIXME: Remove this function (requires refactoring unit tests). | 4057 # FIXME: Remove this function (requires refactoring unit tests). |
| 4046 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None): | 4058 def process_file_data(filename, file_extension, lines, error, min_confidence, fs =None): |
| 4047 checker = CppChecker(filename, file_extension, error, min_confidence, fs) | 4059 checker = CppChecker(filename, file_extension, error, min_confidence, fs) |
| 4048 checker.check(lines) | 4060 checker.check(lines) |
| OLD | NEW |