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

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*> or static_pointer_cast().
inferno 2013/09/18 16:46:04 remove "or static_pointer_cast()". I have an idea
r.kasibhatla 2013/09/19 07:56:56 Done.
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))
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<(\w+\s?\*+\s?)>', line)
3488 if not matched:
3489 return
3490
3491 class_name = re.sub('[\*]', '', matched.group(1))
inferno 2013/09/18 16:46:04 You need to parse ::. otherwise things like 'stati
r.kasibhatla 2013/09/19 07:56:56 Done.
3492 # Ignore (for now) when the casting is to void*,
3493 if class_name == 'void':
3494 return
3495
3496 header_file = ''.join((class_name, '.h'))
3497 matches = check_for_toFoo_definition(header_file, ''.join(('to', class_name) ), error)
3498 # Ignore (for now) if not able to find the header where toFoo might be defin ed.
3499 # TODO: Handle cases where Classname might be defined in some other header.
3500 if matches is None:
3501 return
3502
3503 report_error = True
3504 # Ensure found static_cast instance is not from within toFoo definition itse lf.
3505 if (os.path.basename(processing_file) == header_file):
3506 for item in matches:
3507 if line_number in range(item[1], item[2]):
3508 report_error = False
3509 break
3510
3511 if report_error:
3512 if len(matches):
3513 # toFoo is defined - enforce using it.
3514 # TODO: Suggest an appropriate toFoo from the alternatives present i n matches.
3515 error(line_number, 'readability/check', 4,
3516 'static_cast of class objects is not allowed. Use to%s defined in %s.' %
3517 (class_name, header_file))
3518 else:
3519 # No toFoo defined - enforce definition & usage.
3520 # TODO: Automate the generation of toFoo() to avoid any slippages ev er.
3521 error(line_number, 'readability/check', 4,
3522 'static_cast of class objects is not allowed. Add to%s in %s a nd use it instead.' %
3523 (class_name, header_file))
3524
3525
3424 def check_c_style_cast(line_number, line, raw_line, cast_type, pattern, 3526 def check_c_style_cast(line_number, line, raw_line, cast_type, pattern,
3425 error): 3527 error):
3426 """Checks for a C-style cast by looking for the pattern. 3528 """Checks for a C-style cast by looking for the pattern.
3427 3529
3428 This also handles sizeof(type) warnings, due to similarity of content. 3530 This also handles sizeof(type) warnings, due to similarity of content.
3429 3531
3430 Args: 3532 Args:
3431 line_number: The number of the line to check. 3533 line_number: The number of the line to check.
3432 line: The line of code to check. 3534 line: The line of code to check.
3433 raw_line: The raw line of code to check, with comments. 3535 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) 4015 self.handle_style_error, self.min_confidence)
3914 4016
3915 4017
3916 # FIXME: Remove this function (requires refactoring unit tests). 4018 # FIXME: Remove this function (requires refactoring unit tests).
3917 def process_file_data(filename, file_extension, lines, error, min_confidence, un it_test_config): 4019 def process_file_data(filename, file_extension, lines, error, min_confidence, un it_test_config):
3918 global _unit_test_config 4020 global _unit_test_config
3919 _unit_test_config = unit_test_config 4021 _unit_test_config = unit_test_config
3920 checker = CppChecker(filename, file_extension, error, min_confidence) 4022 checker = CppChecker(filename, file_extension, error, min_confidence)
3921 checker.check(lines) 4023 checker.check(lines)
3922 _unit_test_config = {} 4024 _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