blob: 6764e2cd354971e9f25c008009697db87a3f3f21 [file] [log] [blame]
# Copyright (c) 2011 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import re
class _Intersection(object):
def __init__(self, *tokens):
self._tokens = tokens
def matches(self, tokens):
for token in self._tokens:
if token not in tokens and (token + 's') not in tokens:
return False
return True
class _Area(object):
def __init__(self, name, tokens=None):
self._name = name
self._tokens = tokens if tokens else [self._name_to_token(name)]
def _name_to_token(self, word):
token = word.lower()
return token[:-1] if word[-1] == 's' else token
def matches(self, tokens):
# FIXME: Support pluraization properly
for token in self._tokens:
if isinstance(token, _Intersection):
if token.matches(tokens):
return True
elif token in tokens or (token + 's') in tokens:
return True
return False
def name(self):
return self._name
def tokens(self):
return self._tokens
contribution_areas = [
_Area('ARM JIT', ['arm']),
# FIXME: 'Accelerated compositing / GPU acceleration'
_Area('Accessibility'),
_Area('Android port', ['android']),
_Area('Animation', ['animation', 'animator']),
_Area('Apple\'s Windows port', ['win', 'windows']), # FIXME: need to exclude chromium...
_Area('Basic types and data structures (WTF)', ['wtf']),
# FIXME: 'Bidirectional text'
# FIXME: 'Build/test infrastructure (stuff under Tools/Scripts)'
_Area('CMake Build', ['cmakelist']),
_Area('CSS (Cascading Style Sheets)', ['css']),
_Area('CSS Transforms', [_Intersection('css', 'transforms')]),
_Area('CSS/SVG Filters', [_Intersection('css', 'filters'), _Intersection('svg', 'filters')]),
_Area('CURL HTTP Backend', ['CURL']),
_Area('Resource Cache', [_Intersection('loader', 'cache')]),
_Area('Memory Cache', [_Intersection('graphics', 'cache')]),
_Area('Cairo'),
_Area('Canvas'),
_Area('Chromium Linux', [_Intersection('chromium', 'linux')]),
# FIXME: 'Commit Queue'
_Area('Core DOM', ['dom']),
_Area('Core Graphics', ['cg']),
_Area('Bindings'),
_Area('DOM Storage', ['storage']),
_Area('Drag and Drop', ['drag']),
_Area('DumpRenderTree'),
_Area('Editing / Selection', ['editing']),
_Area('Event Handling', ['event']),
_Area('FastMalloc'),
_Area('File API', ['fileapi']),
_Area('Fonts'),
_Area('Forms'),
# FIXME: 'Frame Flattening'
_Area('Frame Loader'),
# FIXME: 'General' Maybe auto-detect people contributing to all subdirectories?
_Area('Geolocation API', ['geolocation']),
_Area('Graphics', ['graphics']),
_Area('HTML', ['html']),
_Area('HTML Parser', [_Intersection('html', 'parser')]), # FIXME: matches html/track/WebVTTParser.cpp
_Area('HTML5 Media Support', ['media']),
_Area('History', ['history']),
# FIXME: 'Hit testing'
_Area('Image Decoder', ['imagedecoder']),
# FIXME: 'Input methods'
_Area('JSC Bindings', [_Intersection('bindings', 'js')]),
_Area('JavaScriptCore'),
_Area('JavaScriptCore Regular Expressions', [_Intersection('JavaScriptCore', 'regexp')]),
# FIXME: 'Layout tests' but what does it mean to say you're an expert on layout tests? Maybe worked on tools?
_Area('Loader', ['loader']),
_Area('MathML'),
_Area('Memory Use / Leaks', ['leaks']), # Probably need more tokens
_Area('MessagePorts'),
_Area('Network', [_Intersection('platform', 'network')]),
_Area('new-run-webkit-tests', ['layout_tests']),
_Area('OpenVG graphics backend', ['openvg']),
# FIXME: 'Performance'
_Area('Plug-ins', ['plugins']),
_Area('Printing', ['printing', 'print']),
_Area('Rendering'),
_Area('SVG (Scalable Vector Graphics)', ['svg']),
_Area('Scrollbars', ['scroll']),
_Area('Security'), # Probably need more tokens
# FIXME: 'Shadow DOM'
_Area('Soup Network Backend', ['soup']),
# FIXME: 'Spell Checking' just need tokens
_Area('Tables', ['htmltable', 'rendertable']),
# FIXME: 'Text Encoding'
# FIXME: 'Text Layout'
_Area('The Chromium Port', ['chromium']),
_Area('The WebKitGTK+ Port', ['gtk']),
_Area('The Haiku Port', ['haiku']),
_Area('The QtWebKit Port', ['qt']),
_Area('The WinCE Port', ['wince']),
_Area('The WinCairo Port', ['cairo']),
_Area('Threading', ['thread']),
_Area('Tools'),
_Area('Touch Support', ['touch']),
_Area('Transforms', ['transforms']), # There's also CSS transforms
_Area('Transitions', ['transitions']), # This only matches transition events at the moment
_Area('URL Parsing', ['KURL']), # Probably need more tokens
_Area('V8', ['v8']),
_Area('V8 Bindings', [_Intersection('bindings', 'v8')]),
_Area('Web Inspector / Developer Tools', ['inspector']),
_Area('Web Timing', ['PerformanceNavigation', 'PerformanceTiming']), # more tokens?
_Area('WebArchive'),
_Area('WebCore Icon Database', ['icon']),
_Area('WebGL', ['webgl']),
_Area('WebKit Websites', ['websites']),
_Area('WebKit2'),
_Area('WebSQL Databases', [_Intersection('storage', 'database')]),
_Area('WebSockets'),
_Area('Workers'),
_Area('XML'),
_Area('XMLHttpRequest'),
_Area('XSLT'),
_Area('XSSAuditor'),
_Area('WebKit API Tests', ['TestWebKitAPI']),
_Area('webkit-patch', [_Intersection('webkitpy', 'commands')]),
]
class ContributionAreas(object):
def __init__(self, filesystem, table=contribution_areas):
self._filesystem = filesystem
self._contribution_areas = table
def names(self):
return [area.name() for area in self._contribution_areas]
def _split_path(self, path):
result = []
while path and len(path):
next_path, tail = self._filesystem.split(path)
if path == next_path:
break
if tail and len(tail):
result.append(tail)
path = next_path
return result
def _split_camelcase(self, name, transform=lambda x: x):
result = []
while name and len(name):
m = re.match('^([A-Z][a-z0-9]+)|([A-Z0-9]+(?=([A-Z][a-z0-9]|\.|$)))', name)
if m:
result.append(transform(m.group(0)))
name = name[m.end():]
else:
return result
return result
def areas_for_touched_files(self, touched_files):
areas = set()
for file_path in touched_files:
split_file_path = self._split_path(file_path)
tokenized_file_path = None
tokenized_file_path = sum([self._split_camelcase(token, lambda x: x.lower()) for token in split_file_path], [])
for area in self._contribution_areas:
if area.matches(split_file_path) or area.matches(tokenized_file_path):
areas.add(area.name())
return areas