def __init__(self, file_paths): in_generator.Writer.__init__(self, file_paths) properties = self.in_file.name_dictionaries self._descriptors = [property for property in properties if property['descriptor_only']] self._aliases = [property for property in properties if property['alias_for']] properties = [property for property in properties if not property['alias_for']] # 0: CSSPropertyInvalid # 1: CSSPropertyApplyAtRule # 2: CSSPropertyVariable self._first_enum_value = 3 # StylePropertyMetadata additionally assumes there are under 1024 properties. assert self._first_enum_value + len(properties) < 512, 'Property aliasing expects there are under 512 properties.' for offset, property in enumerate(properties): property['property_id'] = name_utilities.enum_for_css_property(property['name']) property['upper_camel_name'] = name_utilities.camel_case(property['name']) property['lower_camel_name'] = name_utilities.lower_first(property['upper_camel_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) for property in self._aliases: property['property_id'] = name_utilities.enum_for_css_property_alias(property['name']) aliased_property = self._properties[name_utilities.enum_for_css_property(property['alias_for'])] property['enum_value'] = aliased_property['enum_value'] + 512 self._properties_including_aliases += self._aliases
def __init__(self, file_paths): in_generator.Writer.__init__(self, file_paths) properties = self.in_file.name_dictionaries self._descriptors = [ property for property in properties if property['descriptor_only'] ] self._aliases = [ property for property in properties if property['alias_for'] ] properties = [ property for property in properties if not property['alias_for'] ] # 0: CSSPropertyInvalid # 1: CSSPropertyApplyAtRule # 2: CSSPropertyVariable self._first_enum_value = 3 # StylePropertyMetadata additionally assumes there are under 1024 properties. assert self._first_enum_value + len( properties ) < 512, 'Property aliasing expects there are under 512 properties.' for offset, property in enumerate(properties): property['property_id'] = name_utilities.enum_for_css_property( property['name']) property['upper_camel_name'] = name_utilities.camel_case( property['name']) property['lower_camel_name'] = name_utilities.lower_first( property['upper_camel_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) for property in self._aliases: property[ 'property_id'] = name_utilities.enum_for_css_property_alias( property['name']) aliased_property = self._properties[ name_utilities.enum_for_css_property(property['alias_for'])] property['enum_value'] = aliased_property['enum_value'] + 512 self._properties_including_aliases += self._aliases
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['aliased_property'] = aliased_property[ 'name'].to_upper_camel_case() updated_alias['property_id'] = enum_for_css_property_alias( alias['name']) updated_alias['enum_value'] = aliased_property['enum_value'] + \ self._alias_offset self._aliases[i] = updated_alias
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'] property_['property_id'] = enum_for_css_property(name) property_['is_internal'] = name.original.startswith('-internal-') method_name = property_['name_for_methods'] if not method_name: method_name = name.to_upper_camel_case().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 + '::' + NameStyleConverter( property_['default_value']).to_enum_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) if property_['direction_aware_options'] and not property_[ 'style_builder_template']: property_['style_builder_template'] = 'direction_aware'
def __init__(self, file_paths): json5_generator.Writer.__init__(self, file_paths) properties = self.json5_file.name_dictionaries # Sort properties by priority, then alphabetically. for property in properties: # 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'] ] # 0: CSSPropertyInvalid # 1: CSSPropertyApplyAtRule # 2: CSSPropertyVariable self._first_enum_value = 3 # StylePropertyMetadata additionally assumes there are under 1024 properties. assert self._first_enum_value + len( properties ) < 512, 'Property aliasing expects there are under 512 properties.' for offset, property in enumerate(properties): property['property_id'] = name_utilities.enum_for_css_property( property['name']) property['upper_camel_name'] = name_utilities.camel_case( property['name']) property['lower_camel_name'] = name_utilities.lower_first( property['upper_camel_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) for property in self._aliases: property[ 'property_id'] = name_utilities.enum_for_css_property_alias( property['name']) aliased_property = self._properties[ name_utilities.enum_for_css_property(property['alias_for'])] property['enum_value'] = aliased_property['enum_value'] + 512 self._properties_including_aliases += self._aliases
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)
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. 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_['is_internal'] = property_['name'].startswith('-internal-') name = property_['name_for_methods'] if not name: name = upper_camel_case(property_['name']).replace('Webkit', '') set_if_none(property_, 'inherited', False) # Initial function, Getters and Setters for ComputedStyle. property_['initial'] = 'Initial' + name simple_type_name = str(property_['type_name']).split('::')[-1] set_if_none(property_, 'name_for_methods', name) set_if_none(property_, 'type_name', 'E' + name) set_if_none( property_, 'getter', name if simple_type_name != name else 'Get' + name) set_if_none(property_, 'setter', 'Set' + name) if property_['inherited']: property_['is_inherited_setter'] = 'Set' + name + 'IsInherited' # Expand whether there are custom StyleBuilder methods. if property_['custom_apply_functions_all']: property_['custom_apply_functions_inherit'] = True property_['custom_apply_functions_initial'] = True property_['custom_apply_functions_value'] = True # Expand StyleBuilderConverter params where ncessary. 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)