blob: 8e509de30915e207d6c36b6ac465ec7efa95c09b [file] [log] [blame]
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import collections
import functools
import itertools
import re
import wayland_protocol_data_classes
import wayland_protocol_utils
def split_for_words(x):
# type: (str) -> Tuple[str, ...]
"""Split underscore_seperated identifiers into a component words."""
return tuple(w.lower() for w in x.split('_'))
def kebab_case(x):
# type: (str) -> str
"""Convert the input identifier to kebab-case"""
return '-'.join(split_for_words(x))
def pascal_case(x):
# type: (str) -> str
"""Convert the input identifier to PascalCase"""
return ''.join(w.title() for w in split_for_words(x))
@wayland_protocol_utils.memoize(cache={})
def get_base_human_readable_name_map(protocols):
# type: (Iterable[Protocol]) -> Dict[str, str]
"""Determines a mapping of each interface name to an identifier name."""
# Default to the full interface name as the identifier.
interface_identifiers = dict((interface.name, interface.name)
for protocol in protocols
for interface in protocol.interfaces)
# Reserve the full interface names as identifiers, so nothing is
# ever shortened to another interface name.
used = set(interface_identifiers.keys())
def set_identifier_name_for_protocol(names, interface):
# type: (Iterable[str], Interface) -> None
"""Set the first unused name in |names| as the name for |interface|"""
for name in names:
if name not in used:
used.add(name)
interface_identifiers[interface.name] = name
return
def set_identifier_names_for_interface(interfaces):
# type: (Iterable[Interface]) -> None
"""Try and set a shorter name for each interface"""
# For each interface in protocol, try and find a shorter name to use
# when representing instances of that interface.
for interface in interfaces:
name = interface.name
name_no_prefix = name.split('_', 1)[-1]
name_no_suffix = re.sub('_v\d+$', '', name)
name_no_prefix_or_suffix = re.sub(r'_v\d+$', '', name_no_prefix)
set_identifier_name_for_protocol(
[name_no_prefix_or_suffix, name_no_prefix, name_no_suffix],
interface)
def prioritize_interfaces(interfaces):
# type: (Iterable[Interface]) -> Tuple[Interface, ...]
DEFAULT_STABLE_PRIORITY = 100
DEFAULT_UNSTABLE_PRIORITY = 101
UNSTABLE_PREFIX = 'z'
prefix_priorities = dict(wl_=0,
wp_=1,
xdg_=2,
zwl_=10,
zwp_=11,
zxdg_=12,
aura_=200,
cr_=201,
zaura_=202,
zcr_=203)
interfaces_by_priority = collections.defaultdict(list)
for protocol in protocols:
for interface in protocol.interfaces:
name = interface.name
priority = DEFAULT_STABLE_PRIORITY if not name.startswith(
UNSTABLE_PREFIX) else DEFAULT_UNSTABLE_PRIORITY
for prefix, prefix_priority in prefix_priorities.items():
if name.startswith(prefix):
priority = prefix_priority
break
interfaces_by_priority[priority].append(interface)
return tuple(
itertools.chain(*tuple(interfaces_by_priority[p]
for p in sorted(interfaces_by_priority))))
set_identifier_names_for_interface(
prioritize_interfaces(
tuple(
itertools.chain(*tuple(protocol.interfaces
for protocol in protocols)))))
return interface_identifiers