cc: Add PRESUBMIT check for passing simple types by value.

This will save reviewer cycles, hooray.

R=enne
BUG=

Review URL: https://chromiumcodereview.appspot.com/14410002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195719 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py
index e82e9abb..e133e9ab 100644
--- a/cc/PRESUBMIT.py
+++ b/cc/PRESUBMIT.py
@@ -9,6 +9,7 @@
 """
 
 import re
+import string
 
 CC_SOURCE_FILES=(r'^cc/.*\.(cc|h)$',)
 CC_PERF_TEST =(r'^.*_perftest.*\.(cc|h)$',)
@@ -56,9 +57,14 @@
       items=notreached_files)]
   return []
 
-def CheckSpamLogging(input_api, output_api, white_list=CC_SOURCE_FILES, black_list=None):
+def CheckSpamLogging(input_api,
+                     output_api,
+                     white_list=CC_SOURCE_FILES,
+                     black_list=None):
   black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
-  source_file_filter = lambda x: input_api.FilterSourceFile(x, white_list, black_list)
+  source_file_filter = lambda x: input_api.FilterSourceFile(x,
+                                                            white_list,
+                                                            black_list)
 
   log_info = []
   printf = []
@@ -80,11 +86,46 @@
       items=printf)]
   return []
 
+def CheckPassByValue(input_api,
+                     output_api,
+                     white_list=CC_SOURCE_FILES,
+                     black_list=None):
+  black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
+  source_file_filter = lambda x: input_api.FilterSourceFile(x,
+                                                            white_list,
+                                                            black_list)
+
+  local_errors = []
+
+  # Well-defined simple classes containing only <= 4 ints, or <= 2 floats.
+  pass_by_value_types = ['base::Time',
+                         'base::TimeTicks',
+                         'gfx::Point',
+                         'gfx::PointF',
+                         'gfx::Rect',
+                         'gfx::Size',
+                         'gfx::SizeF',
+                         'gfx::Vector2d',
+                         'gfx::Vector2dF',
+                         ]
+
+  for f in input_api.AffectedSourceFiles(source_file_filter):
+    contents = input_api.ReadFile(f, 'rb')
+    match = re.search(
+      r'\bconst +' + '(?P<type>(%s))&' %
+        string.join(pass_by_value_types, '|'),
+      contents)
+    if match:
+      local_errors.append(output_api.PresubmitError(
+        '%s passes %s by const ref instead of by value.' %
+        (f.LocalPath(), match.group('type'))))
+  return local_errors
 
 def CheckChangeOnUpload(input_api, output_api):
   results = []
   results += CheckAsserts(input_api, output_api)
   results += CheckSpamLogging(input_api, output_api, black_list=CC_PERF_TEST)
+  results += CheckPassByValue(input_api, output_api)
   results += CheckChangeLintsClean(input_api, output_api)
   return results