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)) | |
Dirk Pranke
2013/09/20 22:34:42
Unfortunately, I think this breaks if you only hav
| |
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.rfind(':') | |
3498 if not namespace_pos == -1: | |
3499 class_name = class_name[namespace_pos + 1:] | |
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 |