author Simon Whitehead <>
Sat, 13 May 2017 15:12:15 -0500
changeset 358329 633151f5d481d49bd39900d43e6a75d77459a7bb
parent 274725 9125a6b6c61d0c97ef293d4f0cfed0615ec7538f
child 374472 e894fa698629c0dc5d6a30dec9b5282d58ad852f
permissions -rw-r--r--
servo: Merge #16829 - Disallow negative duration for animation and transition (from hiikezoe:disallow-negative-duration); r=emilio <!-- Please describe your changes on the following line: --> --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #15343 <!-- Either: --> - [X] There are tests for these changes written by @simon-whitehead . Thank you! <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: Source-Revision: 4613c0382ab76263fb8202ccf52f4c0520e44809

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at

import buildconfig
import collections
import re
import StringIO
import sys

def read_conf(conf_filename):
    # Can't read/write from a single StringIO, so make a new one for reading.
    stream = open(conf_filename, 'rU')

    def parse_counters(stream):
        for line_num, line in enumerate(stream):
            line = line.rstrip('\n')
            if not line or line.startswith('//'):
                # empty line or comment
            m = re.match(r'method ([A-Za-z0-9]+)\.([A-Za-z0-9]+)$', line)
            if m:
                interface_name, method_name = m.groups()
                yield { 'type': 'method',
                        'interface_name': interface_name,
                        'method_name': method_name }
            m = re.match(r'attribute ([A-Za-z0-9]+)\.([A-Za-z0-9]+)$', line)
            if m:
                interface_name, attribute_name = m.groups()
                yield { 'type': 'attribute',
                        'interface_name': interface_name,
                        'attribute_name': attribute_name }
            m = re.match(r'property ([A-Za-z0-9]+)$', line)
            if m:
                property_name =
                yield { 'type': 'property',
                        'property_name': property_name }
            raise ValueError('error parsing %s at line %d' % (conf_filename, line_num))

    return parse_counters(stream)

def generate_histograms(filename):
    # The mapping for use counters to telemetry histograms depends on the
    # ordering of items in the dictionary.
    items = collections.OrderedDict()
    for counter in read_conf(filename):
        def append_counter(name, desc):
            items[name] = { 'expires_in_version': 'never',
                            'kind' : 'boolean',
                            'description': desc }

        def append_counters(name, desc):
            append_counter('USE_COUNTER2_%s_DOCUMENT' % name, 'Whether a document %s' % desc)
            append_counter('USE_COUNTER2_%s_PAGE' % name, 'Whether a page %s' % desc)

        if counter['type'] == 'method':
            method = '%s.%s' % (counter['interface_name'], counter['method_name'])
            append_counters(method.replace('.', '_').upper(), 'called %s' % method)
        elif counter['type'] == 'attribute':
            attr = '%s.%s' % (counter['interface_name'], counter['attribute_name'])
            counter_name = attr.replace('.', '_').upper()
            append_counters('%s_getter' % counter_name, 'got %s' % attr)
            append_counters('%s_setter' % counter_name, 'set %s' % attr)
        elif counter['type'] == 'property':
            prop = counter['property_name']
            append_counters('PROPERTY_%s' % prop.replace('-', '_').upper(), "used the '%s' property" % prop)

    return items