def expand_aliases(self):
     for i, alias in enumerate(self._aliases):
         assert not alias['runtime_flag'], \
             "Property '{}' is an alias with a runtime_flag, "\
             "but runtime flags do not currently work for aliases.".format(
                 alias['name'])
         aliased_property = self._properties_by_id[
             enum_for_css_property(alias['alias_for'])]
         updated_alias = aliased_property.copy()
         updated_alias['name'] = alias['name']
         updated_alias['alias_for'] = alias['alias_for']
         updated_alias['property_id'] = enum_for_css_property_alias(
             alias['name'])
         updated_alias['enum_value'] = aliased_property['enum_value'] + \
             self._alias_offset
         updated_alias['upper_camel_name'] = upper_camel_case(alias['name'])
         updated_alias['lower_camel_name'] = lower_camel_case(alias['name'])
         self._aliases[i] = updated_alias
Exemple #2
0
    def __init__(self, file_paths):
        json5_generator.Writer.__init__(self, file_paths)

        # StylePropertyMetadata assumes that there are at most 1024 properties + aliases.
        self._alias_offset = 512
        # 0: CSSPropertyInvalid
        # 1: CSSPropertyApplyAtRule
        # 2: CSSPropertyVariable
        self._first_enum_value = 3

        properties = self.json5_file.name_dictionaries

        # Sort properties by priority, then alphabetically.
        for property in properties:
            check_property_parameters(property)
            # This order must match the order in CSSPropertyPriority.h.
            priority_numbers = {'Animation': 0, 'High': 1, 'Low': 2}
            priority = priority_numbers[property['priority']]
            name_without_leading_dash = property['name']
            if property['name'].startswith('-'):
                name_without_leading_dash = property['name'][1:]
            property['sorting_key'] = (priority, name_without_leading_dash)

        # Assert there are no key collisions.
        sorting_keys = [p['sorting_key'] for p in properties]
        assert len(sorting_keys) == len(set(sorting_keys)), \
            ('Collision detected - two properties have the same name and priority, '
             'a potentially non-deterministic ordering can occur.')
        properties.sort(key=lambda p: p['sorting_key'])

        self._aliases = [
            property for property in properties if property['alias_for']
        ]
        properties = [
            property for property in properties if not property['alias_for']
        ]

        assert (
            self._first_enum_value + len(properties) < self._alias_offset), (
                'Property aliasing expects there are under %d properties.' %
                self._alias_offset)

        for property in properties:
            assert property['is_descriptor'] or property['is_property'], \
                property['name'] + ' must be either a property, a descriptor' +\
                ' or both'

        for offset, property in enumerate(properties):
            property['property_id'] = enum_for_css_property(property['name'])
            property['upper_camel_name'] = upper_camel_case(property['name'])
            property['lower_camel_name'] = lower_camel_case(property['name'])
            property['enum_value'] = self._first_enum_value + offset
            property['is_internal'] = property['name'].startswith('-internal-')

        self._properties_including_aliases = properties
        self._properties = {
            property['property_id']: property
            for property in properties
        }

        # The generated code will only work with at most one alias per property.
        assert len({property['alias_for']
                    for property in self._aliases}) == len(self._aliases)

        # Check that alias_for is not being used with a runtime flag.
        for property_ in self._aliases:
            assert not property_['runtime_flag'], \
                ("Property '" + property_['name'] + "' is an alias with a runtime_flag, "
                 "but runtime flags do not currently work for aliases.")

        # Update property aliases to include the fields of the property being aliased.
        for i, alias in enumerate(self._aliases):
            aliased_property = self._properties[enum_for_css_property(
                alias['alias_for'])]
            updated_alias = aliased_property.copy()
            updated_alias['name'] = alias['name']
            updated_alias['alias_for'] = alias['alias_for']
            updated_alias['property_id'] = enum_for_css_property_alias(
                alias['name'])
            updated_alias['enum_value'] = aliased_property[
                'enum_value'] + self._alias_offset
            updated_alias['upper_camel_name'] = upper_camel_case(alias['name'])
            updated_alias['lower_camel_name'] = lower_camel_case(alias['name'])
            self._aliases[i] = updated_alias
        self._properties_including_aliases += self._aliases

        self.last_unresolved_property_id = max(
            property["enum_value"]
            for property in self._properties_including_aliases)
Exemple #3
0
    def expand_parameters(self, property_):
        def set_if_none(property_, key, value):
            if key not in property_ or property_[key] is None:
                property_[key] = value

        # Basic info.
        name = property_['name'].original
        property_['property_id'] = enum_for_css_property(name)
        property_['upper_camel_name'] = upper_camel_case(name)
        property_['lower_camel_name'] = lower_camel_case(name)
        property_['is_internal'] = name.startswith('-internal-')
        method_name = property_['name_for_methods']
        if not method_name:
            method_name = upper_camel_case(name).replace('Webkit', '')
        set_if_none(property_, 'inherited', False)

        # Initial function, Getters and Setters for ComputedStyle.
        property_['initial'] = 'Initial' + method_name
        simple_type_name = str(property_['type_name']).split('::')[-1]
        set_if_none(property_, 'name_for_methods', method_name)
        set_if_none(property_, 'type_name', 'E' + method_name)
        set_if_none(
            property_,
            'getter',
            method_name if simple_type_name != method_name else 'Get' + method_name)
        set_if_none(property_, 'setter', 'Set' + method_name)
        if property_['inherited']:
            property_['is_inherited_setter'] = 'Set' + method_name + 'IsInherited'

        # Figure out whether we should generate style builder implementations.
        for x in ['initial', 'inherit', 'value']:
            suppressed = x in property_['style_builder_custom_functions']
            property_['style_builder_generate_%s' % x] = not suppressed

        # Expand StyleBuilderConverter params where necessary.
        if property_['type_name'] in PRIMITIVE_TYPES:
            set_if_none(property_, 'converter', 'CSSPrimitiveValue')
        else:
            set_if_none(property_, 'converter', 'CSSIdentifierValue')

        # Expand out field templates.
        if property_['field_template']:
            self._field_alias_expander.expand_field_alias(property_)

            type_name = property_['type_name']
            if (property_['field_template'] == 'keyword' or
                    property_['field_template'] == 'multi_keyword'):
                default_value = type_name + '::' + \
                    enum_value_name(property_['default_value'])
            elif (property_['field_template'] == 'external' or
                  property_['field_template'] == 'primitive' or
                  property_['field_template'] == 'pointer'):
                default_value = property_['default_value']
            else:
                assert property_['field_template'] == 'monotonic_flag', \
                    "Please put a valid value for field_template; got " + \
                    str(property_['field_template'])
                property_['type_name'] = 'bool'
                default_value = 'false'
            property_['default_value'] = default_value

            property_['unwrapped_type_name'] = property_['type_name']
            if property_['wrapper_pointer_name']:
                assert property_['field_template'] in ['pointer', 'external']
                if property_['field_template'] == 'external':
                    property_['type_name'] = '{}<{}>'.format(
                        property_['wrapper_pointer_name'], type_name)

        # Default values for extra parameters in ComputedStyleExtraFields.json5.
        set_if_none(property_, 'custom_copy', False)
        set_if_none(property_, 'custom_compare', False)
        set_if_none(property_, 'mutable', False)