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 3266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3277 error(line_number, 'runtime/bitfields', 5, | 3277 error(line_number, 'runtime/bitfields', 5, |
| 3278 'Please declare integral type bitfields with either signed or unsi gned.') | 3278 'Please declare integral type bitfields with either signed or unsi gned.') |
| 3279 | 3279 |
| 3280 check_identifier_name_in_declaration(filename, line_number, line, file_state , error) | 3280 check_identifier_name_in_declaration(filename, line_number, line, file_state , error) |
| 3281 | 3281 |
| 3282 # Check for unsigned int (should be just 'unsigned') | 3282 # Check for unsigned int (should be just 'unsigned') |
| 3283 if search(r'\bunsigned int\b', line): | 3283 if search(r'\bunsigned int\b', line): |
| 3284 error(line_number, 'runtime/unsigned', 1, | 3284 error(line_number, 'runtime/unsigned', 1, |
| 3285 'Omit int when using unsigned') | 3285 'Omit int when using unsigned') |
| 3286 | 3286 |
| 3287 # Check that we're not using static_cast<Text*>. | 3287 # Check for usage of static_cast<Classname*>. |
| 3288 if search(r'\bstatic_cast<Text\*>', line): | 3288 check_for_object_static_cast(filename, line_number, line, error) |
| 3289 error(line_number, 'readability/check', 4, | 3289 |
| 3290 'Consider using toText helper function in WebCore/dom/Text.h ' | |
| 3291 'instead of static_cast<Text*>') | |
| 3292 | 3290 |
| 3293 def check_identifier_name_in_declaration(filename, line_number, line, file_state , error): | 3291 def check_identifier_name_in_declaration(filename, line_number, line, file_state , error): |
| 3294 """Checks if identifier names contain any underscores. | 3292 """Checks if identifier names contain any underscores. |
| 3295 | 3293 |
| 3296 As identifiers in libraries we are using have a bunch of | 3294 As identifiers in libraries we are using have a bunch of |
| 3297 underscores, we only warn about the declarations of identifiers | 3295 underscores, we only warn about the declarations of identifiers |
| 3298 and don't check use of identifiers. | 3296 and don't check use of identifiers. |
| 3299 | 3297 |
| 3300 Args: | 3298 Args: |
| 3301 filename: The name of the current file. | 3299 filename: The name of the current file. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3414 return | 3412 return |
| 3415 # We should continue checking if this is a function | 3413 # We should continue checking if this is a function |
| 3416 # declaration because we need to check its arguments. | 3414 # declaration because we need to check its arguments. |
| 3417 # Also, we need to check multiple declarations. | 3415 # Also, we need to check multiple declarations. |
| 3418 if character_after_identifier != '(' and character_after_identifier != ' ,': | 3416 if character_after_identifier != '(' and character_after_identifier != ' ,': |
| 3419 return | 3417 return |
| 3420 | 3418 |
| 3421 number_of_identifiers += 1 | 3419 number_of_identifiers += 1 |
| 3422 line = line[matched.end():] | 3420 line = line[matched.end():] |
| 3423 | 3421 |
| 3422 | |
| 3423 def check_for_toFoo_definition(filename, pattern, error): | |
| 3424 """ Reports for using static_cast instead of toFoo convenience function. | |
| 3425 | |
| 3426 This function will output warnings to make sure you are actually using | |
| 3427 the added toFoo conversion functions rather than directly hard coding | |
| 3428 the static_cast<Classname*> call. For example, you should toHTMLELement(Node *) | |
| 3429 to convert Node* to HTMLElement*, instead of static_cast<HTMLElement*>(Node* ) | |
| 3430 | |
| 3431 Args: | |
| 3432 filename: The name of the header file in which to check for toFoo definiti on. | |
| 3433 pattern: The conversion function pattern to grep for. | |
| 3434 error: The function to call with any errors found. | |
| 3435 """ | |
| 3436 def get_abs_filepath(filename, subdirectory=None): | |
| 3437 if subdirectory: | |
| 3438 start_dir = subdirectory | |
| 3439 else: | |
| 3440 start_dir = os.path.dirname(os.path.abspath(filename)) | |
| 3441 | |
| 3442 for root, dirs, names in os.walk(start_dir): | |
| 3443 if filename in names: | |
| 3444 return os.path.join(root, filename) | |
| 3445 return None | |
| 3446 | |
| 3447 def grep(lines, pattern, error): | |
| 3448 matches = [] | |
| 3449 function_state = None | |
| 3450 for line_number in xrange(lines.num_lines()): | |
| 3451 line = (lines.elided[line_number]).rstrip() | |
| 3452 if pattern in line: | |
| 3453 if not function_state: | |
| 3454 function_state = _FunctionState(1) | |
| 3455 detect_functions(lines, line_number, function_state, error) | |
| 3456 # Exclude the match of dummy conversion function. Dummy function is just to | |
| 3457 # catch invalid conversions and shouldn't be part of possible al ternatives. | |
| 3458 result = re.search(r'%s(\s+)%s' % ("void", pattern), line) | |
| 3459 if not result: | |
| 3460 matches.append([line, function_state.body_start_position.row , function_state.end_position.row + 1]) | |
| 3461 function_state = None | |
| 3462 | |
| 3463 return matches | |
| 3464 | |
| 3465 file_path = get_abs_filepath(filename) | |
| 3466 if not file_path: | |
| 3467 return None | |
| 3468 | |
| 3469 f = open(file_path) | |
| 3470 clean_lines = CleansedLines(f.readlines()) | |
| 3471 f.close() | |
| 3472 | |
| 3473 # Make a list of all genuine alternatives to static_cast. | |
| 3474 matches = grep(clean_lines, pattern, error) | |
| 3475 return matches | |
| 3476 | |
| 3477 | |
| 3478 def check_for_object_static_cast(processing_file, line_number, line, error): | |
| 3479 """Checks for a Cpp-style static cast on objects by looking for the pattern. | |
| 3480 | |
| 3481 Args: | |
| 3482 processing_file: The name of the processing file. | |
| 3483 line_number: The number of the line to check. | |
| 3484 line: The line of code to check. | |
| 3485 error: The function to call with any errors found. | |
| 3486 """ | |
| 3487 matched = search(r'\bstatic_cast<(\s*\w*:?:?\w+\s*\*+\s*)>', line) | |
| 3488 if not matched: | |
| 3489 return | |
| 3490 | |
| 3491 class_name = re.sub('[\*]', '', matched.group(1)) | |
| 3492 class_name = class_name.strip() | |
| 3493 # Ignore (for now) when the casting is to void*, | |
| 3494 if class_name == 'void': | |
| 3495 return | |
| 3496 | |
| 3497 namespace_pos = class_name.find(':') | |
|
inferno
2013/09/19 14:32:45
Do a rfind and then class_name = class_name[namesp
| |
| 3498 if not namespace_pos == -1: | |
| 3499 class_name = class_name[namespace_pos + 2:] | |
| 3500 | |
| 3501 header_file = ''.join((class_name, '.h')) | |
| 3502 matches = check_for_toFoo_definition(header_file, ''.join(('to', class_name) ), error) | |
| 3503 # Ignore (for now) if not able to find the header where toFoo might be defin ed. | |
| 3504 # TODO: Handle cases where Classname might be defined in some other header. | |
| 3505 if matches is None: | |
| 3506 return | |
| 3507 | |
| 3508 report_error = True | |
| 3509 # Ensure found static_cast instance is not from within toFoo definition itse lf. | |
| 3510 if (os.path.basename(processing_file) == header_file): | |
| 3511 for item in matches: | |
| 3512 if line_number in range(item[1], item[2]): | |
| 3513 report_error = False | |
| 3514 break | |
| 3515 | |
| 3516 if report_error: | |
| 3517 if len(matches): | |
| 3518 # toFoo is defined - enforce using it. | |
| 3519 # TODO: Suggest an appropriate toFoo from the alternatives present i n matches. | |
| 3520 error(line_number, 'readability/check', 4, | |
| 3521 'static_cast of class objects is not allowed. Use to%s defined in %s.' % | |
| 3522 (class_name, header_file)) | |
| 3523 else: | |
| 3524 # No toFoo defined - enforce definition & usage. | |
| 3525 # TODO: Automate the generation of toFoo() to avoid any slippages ev er. | |
| 3526 error(line_number, 'readability/check', 4, | |
| 3527 'static_cast of class objects is not allowed. Add to%s in %s a nd use it instead.' % | |
| 3528 (class_name, header_file)) | |
| 3529 | |
| 3530 | |
| 3424 def check_c_style_cast(line_number, line, raw_line, cast_type, pattern, | 3531 def check_c_style_cast(line_number, line, raw_line, cast_type, pattern, |
| 3425 error): | 3532 error): |
| 3426 """Checks for a C-style cast by looking for the pattern. | 3533 """Checks for a C-style cast by looking for the pattern. |
| 3427 | 3534 |
| 3428 This also handles sizeof(type) warnings, due to similarity of content. | 3535 This also handles sizeof(type) warnings, due to similarity of content. |
| 3429 | 3536 |
| 3430 Args: | 3537 Args: |
| 3431 line_number: The number of the line to check. | 3538 line_number: The number of the line to check. |
| 3432 line: The line of code to check. | 3539 line: The line of code to check. |
| 3433 raw_line: The raw line of code to check, with comments. | 3540 raw_line: The raw line of code to check, with comments. |
| (...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3913 self.handle_style_error, self.min_confidence) | 4020 self.handle_style_error, self.min_confidence) |
| 3914 | 4021 |
| 3915 | 4022 |
| 3916 # FIXME: Remove this function (requires refactoring unit tests). | 4023 # FIXME: Remove this function (requires refactoring unit tests). |
| 3917 def process_file_data(filename, file_extension, lines, error, min_confidence, un it_test_config): | 4024 def process_file_data(filename, file_extension, lines, error, min_confidence, un it_test_config): |
| 3918 global _unit_test_config | 4025 global _unit_test_config |
| 3919 _unit_test_config = unit_test_config | 4026 _unit_test_config = unit_test_config |
| 3920 checker = CppChecker(filename, file_extension, error, min_confidence) | 4027 checker = CppChecker(filename, file_extension, error, min_confidence) |
| 3921 checker.check(lines) | 4028 checker.check(lines) |
| 3922 _unit_test_config = {} | 4029 _unit_test_config = {} |
| OLD | NEW |