Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: Tools/Scripts/webkitpy/style/checkers/cpp.py

Issue 23654034: Add code style check error for using static_cast instead of toFoo function. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 = {}
OLDNEW
« no previous file with comments | « no previous file | Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698