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

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

Issue 145033013: Update the static_cast style check to check for DEFINE_TYPE_CASTS patterns as well. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 11 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
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 3393 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698