Exemplo n.º 1
0
 def create_method(self, idl_operation, arguments):
     name_converter = NameStyleConverter(idl_operation.name)
     return_type = self.type_resolver.type_from_definition(idl_operation)
     return {
         'name': name_converter.to_upper_camel_case(),
         'type': return_type,
         'arguments': arguments
     }
    def test_in_origin_trials_flag(self):
        features = [
            {
                'name': NameStyleConverter('a'),
                'depends_on': [],
                'origin_trial_feature_name': None
            },
            {
                'name': NameStyleConverter('b'),
                'depends_on': ['a'],
                'origin_trial_feature_name': 'OriginTrials'
            },
            {
                'name': NameStyleConverter('c'),
                'depends_on': ['b'],
                'origin_trial_feature_name': None
            },
            {
                'name': NameStyleConverter('d'),
                'depends_on': ['b'],
                'origin_trial_feature_name': None
            },
            {
                'name': NameStyleConverter('e'),
                'depends_on': ['d'],
                'origin_trial_feature_name': None
            },
        ]
        self.assertSetEqual(util.origin_trials(features), {'b', 'c', 'd', 'e'})

        features = [{
            'name': 'a',
            'depends_on': ['x'],
            'origin_trial_feature_name': None
        }, {
            'name': 'b',
            'depends_on': ['x', 'y'],
            'origin_trial_feature_name': None
        }, {
            'name': 'c',
            'depends_on': ['y', 'z'],
            'origin_trial_feature_name': None
        }, {
            'name': 'x',
            'depends_on': [],
            'origin_trial_feature_name': None
        }, {
            'name': 'y',
            'depends_on': ['x'],
            'origin_trial_feature_name': 'y'
        }, {
            'name': 'z',
            'depends_on': ['y'],
            'origin_trial_feature_name': None
        }]

        self.assertSetEqual(util.origin_trials(features), {'b', 'c', 'y', 'z'})
def agent_name_to_include(config, agent_name):
    include_path = agent_config(
        config, agent_name,
        "include_path") or config["settings"]["include_path"]
    agent_class = agent_name_to_class(config, agent_name)
    return os.path.join(include_path,
                        NameStyleConverter(agent_class).to_snake_case() + ".h")
Exemplo n.º 4
0
def cpp_content_attribute_value_name(interface, value):
    if value == '':
        return 'g_empty_atom'
    if not value:
        return value
    includes.add('core/keywords.h')
    return 'keywords::' + NameStyleConverter(value).to_enum_value()
Exemplo n.º 5
0
class MakeMediaFeaturesWriter(json5_generator.Writer):
    default_metadata = {
        'namespace': '',
        'export': '',
    }
    filters = {
        'symbol':
        media_feature_symbol.getMediaFeatureSymbolWithSuffix(''),
        'to_function_name':
        lambda symbol: NameStyleConverter(symbol).to_function_name(),
    }

    def __init__(self, json5_file_path, output_dir):
        super(MakeMediaFeaturesWriter, self).__init__(json5_file_path,
                                                      output_dir)

        self._outputs = {
            ('media_features.h'): self.generate_header,
        }
        self._template_context = {
            'entries':
            self.json5_file.name_dictionaries,
            'input_files':
            self._input_files,
            'header_guard':
            self.make_header_guard(self._relative_output_dir +
                                   'media_festures.h')
        }

    @template_expander.use_jinja('core/css/templates/media_features.h.tmpl',
                                 filters=filters)
    def generate_header(self):
        return self._template_context
Exemplo n.º 6
0
def v8_value_to_local_cpp_value(interface_name, method, argument, index):
    extended_attributes = argument.extended_attributes
    idl_type = argument.idl_type
    name = NameStyleConverter(argument.name).to_snake_case()
    v8_value = 'info[{index}]'.format(index=index)

    # History.pushState and History.replaceState are explicitly specified as
    # serializing the value for storage. The default is to not serialize for
    # storage. See https://html.spec.whatwg.org/C/#dom-history-pushstate
    if idl_type.name == 'SerializedScriptValue':
        for_storage = (interface_name == 'History'
                       and method.name in ('pushState', 'replaceState'))
        return v8_value_to_local_cpp_ssv_value(extended_attributes,
                                               idl_type,
                                               v8_value,
                                               name,
                                               for_storage=for_storage)

    if argument.is_variadic:
        return v8_value_to_local_cpp_variadic_value(argument, index)
    return idl_type.v8_value_to_local_cpp_value(
        extended_attributes,
        v8_value,
        name,
        declare_variable=False,
        use_exception_state=method.returns_promise)
Exemplo n.º 7
0
    def _determine_blink_headers(self):
        irs = self._ir_map.irs_of_kinds(
            IRMap.IR.Kind.INTERFACE, IRMap.IR.Kind.INTERFACE_MIXIN,
            IRMap.IR.Kind.NAMESPACE, IRMap.IR.Kind.PARTIAL_INTERFACE,
            IRMap.IR.Kind.PARTIAL_INTERFACE_MIXIN,
            IRMap.IR.Kind.PARTIAL_NAMESPACE)

        self._ir_map.move_to_new_phase()

        for old_ir in irs:
            new_ir = self._maybe_make_copy(old_ir)
            self._ir_map.add(new_ir)

            if (new_ir.is_mixin and 'LegacyTreatAsPartialInterface' not in
                    new_ir.extended_attributes):
                continue

            basepath, _ = posixpath.splitext(
                new_ir.debug_info.location.filepath)
            dirpath, filename = posixpath.split(basepath)
            impl_class = new_ir.extended_attributes.value_of('ImplementedAs')
            if impl_class:
                filename = NameStyleConverter(impl_class).to_snake_case()
            header = posixpath.join(dirpath,
                                    posixpath.extsep.join([filename, 'h']))
            new_ir.code_generator_info.set_blink_headers([header])
Exemplo n.º 8
0
def argument_context(interface, method, argument, index, is_visible=True):
    extended_attributes = argument.extended_attributes
    idl_type = argument.idl_type
    if is_visible:
        idl_type.add_includes_for_type(extended_attributes)
    this_cpp_value = cpp_value(interface, method, index)
    is_variadic_wrapper_type = argument.is_variadic and idl_type.is_wrapper_type

    has_type_checking_interface = idl_type.is_wrapper_type

    set_default_value = argument.set_default_value
    this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes,
                                           raw_type=True,
                                           used_as_variadic_argument=argument.is_variadic)
    snake_case_name = NameStyleConverter(argument.name).to_snake_case()
    context = {
        'cpp_type': (
            v8_types.cpp_template_type('base::Optional', this_cpp_type)
            if idl_type.is_explicit_nullable and not argument.is_variadic
            else this_cpp_type),
        'cpp_value': this_cpp_value,
        # FIXME: check that the default value's type is compatible with the argument's
        'enum_type': idl_type.enum_type,
        'enum_values': idl_type.enum_values,
        'handle': '%s_handle' % snake_case_name,
        # TODO(peria): remove once [DefaultValue] removed and just use
        # argument.default_value. https://crbug.com/924419
        'has_default': 'DefaultValue' in extended_attributes or set_default_value,
        'has_type_checking_interface': has_type_checking_interface,
        # Dictionary is special-cased, but arrays and sequences shouldn't be
        'idl_type': idl_type.base_type,
        'idl_type_object': idl_type,
        'index': index,
        'is_callback_function': idl_type.is_callback_function,
        'is_callback_interface': idl_type.is_callback_interface,
        # FIXME: Remove generic 'Dictionary' special-casing
        'is_dictionary': idl_type.is_dictionary or idl_type.base_type == 'Dictionary',
        'is_explicit_nullable': idl_type.is_explicit_nullable,
        'is_nullable': idl_type.is_nullable,
        'is_optional': argument.is_optional,
        'is_variadic': argument.is_variadic,
        'is_variadic_wrapper_type': is_variadic_wrapper_type,
        'is_wrapper_type': idl_type.is_wrapper_type,
        'local_cpp_variable': snake_case_name,
        'name': argument.name,
        'set_default_value': set_default_value,
        'use_permissive_dictionary_conversion': 'PermissiveDictionaryConversion' in extended_attributes,
        'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
        'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
        'v8_value_to_local_cpp_value': v8_value_to_local_cpp_value(interface.name, method, argument, index),
    }
    context.update({
        'is_optional_without_default_value':
            context['is_optional'] and
            not context['has_default'] and
            not context['is_dictionary'] and
            not context['is_callback_interface'],
    })
    return context
Exemplo n.º 9
0
    def test_init_graph(self):
        features = [
            {
                'name': NameStyleConverter('a')
            },
            {
                'name': NameStyleConverter('b')
            },
            {
                'name': NameStyleConverter('c')
            },
        ]

        graph = util.init_graph(features)
        self.assertEqual(len(features), len(graph))
        for node in graph:
            self.assertEqual(len(graph[node]), 0)
Exemplo n.º 10
0
def agent_name_to_include(config, agent_name):
    include_path = agent_config(
        config, agent_name,
        "include_path") or config["settings"]["include_path"]
    agent_class = agent_name_to_class(config, agent_name)
    include_file = os.path.join(
        include_path,
        NameStyleConverter(agent_class).to_snake_case() + ".h")
    return include_file.replace("dev_tools", "devtools")
    def __init__(self, field_role, name_for_methods, property_name, type_name,
                 wrapper_pointer_name, field_template, size, default_value,
                 custom_copy, custom_compare, mutable, getter_method_name,
                 setter_method_name, initial_method_name,
                 computed_style_custom_functions, **kwargs):
        name_source = NameStyleConverter(name_for_methods)
        self.name = name_source.to_class_data_member()
        self.property_name = property_name
        self.type_name = type_name
        self.wrapper_pointer_name = wrapper_pointer_name
        self.alignment_type = self.wrapper_pointer_name or self.type_name
        self.field_template = field_template
        self.size = size
        self.default_value = default_value
        self.custom_copy = custom_copy
        self.custom_compare = custom_compare
        self.mutable = mutable
        self.group = None

        # Method names
        self.getter_method_name = getter_method_name
        self.setter_method_name = setter_method_name
        self.internal_getter_method_name = name_source.to_function_name(
            suffix='internal')
        self.internal_mutable_method_name = name_source.to_function_name(
            prefix='mutable', suffix='internal')
        self.internal_setter_method_name = NameStyleConverter(
            setter_method_name).to_function_name(suffix='internal')
        self.initial_method_name = initial_method_name
        self.resetter_method_name = name_source.to_function_name(
            prefix='reset')
        self.computed_style_custom_functions = computed_style_custom_functions
        # Only bitfields have sizes.
        self.is_bit_field = self.size is not None

        # Field role: one of these must be true
        self.is_property = field_role == 'property'
        self.is_inherited_flag = field_role == 'inherited_flag'
        assert (self.is_property, self.is_inherited_flag).count(True) == 1, \
            'Field role has to be exactly one of: property, inherited_flag'

        if not self.is_inherited_flag:
            self.is_inherited = kwargs.pop('inherited')
            self.is_independent = kwargs.pop('independent')
            self.is_semi_independent_variable = kwargs.pop(
                'semi_independent_variable')
            assert self.is_inherited or not self.is_independent, \
                'Only inherited fields can be independent'

            self.is_inherited_method_name = name_source.to_function_name(
                suffix=['is', 'inherited'])
        assert len(kwargs) == 0, \
            'Unexpected arguments provided to Field: ' + str(kwargs)
Exemplo n.º 12
0
def scoped_content_attribute_name(interface, attribute):
    content_attribute_name = attribute.extended_attributes['Reflect'] or attribute.name.lower()
    symbol_name = 'k' + NameStyleConverter(content_attribute_name).to_upper_camel_case()
    if interface.name.startswith('SVG'):
        namespace = 'svg_names'
        includes.add('core/svg_names.h')
    else:
        namespace = 'html_names'
        includes.add('core/html_names.h')
    return '%s::%sAttr' % (namespace, symbol_name)
Exemplo n.º 13
0
def cpp_name(definition_or_member):
    extended_attributes = definition_or_member.extended_attributes
    if extended_attributes and 'ImplementedAs' in extended_attributes:
        return extended_attributes['ImplementedAs']
    # WebIDL identifiers can contain hyphens[1], but C++ identifiers cannot.
    # Therefore camelCase hyphen-containing identifiers.
    #
    # [1] https://heycam.github.io/webidl/#prod-identifier
    if '-' in definition_or_member.name:
        return NameStyleConverter(definition_or_member.name).to_lower_camel_case()
    return definition_or_member.name
Exemplo n.º 14
0
def v8_value_to_local_cpp_variadic_value(argument, index):
    assert argument.is_variadic
    idl_type = v8_types.native_value_traits_type_name(argument.idl_type,
                                                      argument.extended_attributes, True)

    return {
        'assign_expression': 'ToImplArguments<%s>(info, %s, exception_state)' % (idl_type, index),
        'check_expression': 'exception_state.HadException()',
        'cpp_name': NameStyleConverter(argument.name).to_snake_case(),
        'declare_variable': False,
    }
Exemplo n.º 15
0
    def _replace_include_path(self, match):
        include_or_import = match.group(1)
        path = match.group(2)

        # If |path| starts with 'blink/public/resources', we should prepend
        # 'third_party/'.
        #
        # If |path| starts with 'third_party/WebKit', we should adjust the
        # directory name for third_party/blink, and replace its basename by
        # self._basename_map.
        #
        # If |path| starts with a Blink-internal directory such as bindings,
        # core, modules, platform, public, it refers to a checked-in file, or a
        # generated file. For the former, we should add 'third_party/blink/' and
        # replace the basename.  For the latter, we should update the basename
        # for a name mapped from an IDL renaming, and should add
        # 'third_party/blink/'.

        if path.startswith('blink/public/resources'):
            path = path.replace('blink/public', 'third_party/blink/public')
            return '#%s "%s"' % (include_or_import, path)

        if path.startswith('third_party/WebKit'):
            path = path.replace('third_party/WebKit/Source',
                                'third_party/blink/renderer')
            path = path.replace('third_party/WebKit/common',
                                'third_party/blink/common')
            path = path.replace('third_party/WebKit/public',
                                'third_party/blink/public')
            path = self._update_basename(path)
            return '#%s "%s"' % (include_or_import, path)

        match = None
        for regex in self._checked_in_header_re_list:
            match = regex.search(path)
            if match:
                break
        if match:
            if match.group(1) in self._basename_map:
                path = path[:match.start(1)] + self._basename_map[match.group(
                    1)]
        elif 'core/inspector/protocol/' not in path:
            basename_start = path.rfind('/') + 1
            basename = path[basename_start:]
            if basename in self._idl_generated_impl_headers:
                path = path[:basename_start] + self._basename_map[basename]
            elif basename.startswith('V8'):
                path = path[:basename_start] + NameStyleConverter(
                    basename[:len(basename) - 2]).to_snake_case() + '.h'
        if path.startswith('public'):
            path = 'third_party/blink/' + path
        else:
            path = 'third_party/blink/renderer/' + path
        return '#%s "%s"' % (include_or_import, path)
Exemplo n.º 16
0
class ElementLookupTrieWriter(json5_generator.Writer):
    # FIXME: Inherit all these from somewhere.
    default_parameters = {
        'JSInterfaceName': {},
        'constructorNeedsCreateElementFlags': {},
        'interfaceHeaderDir': {},
        'interfaceName': {},
        'noConstructor': {},
        'noTypeHelpers': {},
        'runtimeEnabled': {},
    }
    default_metadata = {
        'attrsNullNamespace': None,
        'export': '',
        'fallbackInterfaceName': '',
        'fallbackJSInterfaceName': '',
        'namespace': '',
        'namespacePrefix': '',
        'namespaceURI': '',
    }
    filters = {
        'symbol':
        lambda symbol: 'k' + NameStyleConverter(symbol).to_upper_camel_case()
    }

    def __init__(self, json5_file_paths, output_dir):
        super(ElementLookupTrieWriter, self).__init__(json5_file_paths,
                                                      output_dir)
        self._tags = {}
        for entry in self.json5_file.name_dictionaries:
            self._tags[entry['name'].original] = entry['name'].original
        self._namespace = self.json5_file.metadata['namespace'].strip('"')
        basename = self._namespace.lower() + '_element_lookup_trie'
        self._outputs = {
            (basename + '.h'): self.generate_header,
            (basename + '.cc'): self.generate_implementation,
        }

    @template_expander.use_jinja('templates/element_lookup_trie.h.tmpl')
    def generate_header(self):
        return {
            'input_files': self._input_files,
            'namespace': self._namespace,
        }

    @template_expander.use_jinja(
        'templates/element_lookup_trie.cc.tmpl', filters=filters)
    def generate_implementation(self):
        return {
            'input_files': self._input_files,
            'namespace': self._namespace,
            'length_tries': trie_builder.trie_list_by_str_length(self._tags)
        }
Exemplo n.º 17
0
    def test_origin_trials(self):
        features = [
            _feature(NameStyleConverter('a')),
            _feature(NameStyleConverter('b'),
                     depends_on=['a'],
                     origin_trial_feature_name='b'),
            _feature(NameStyleConverter('c'), depends_on=['b']),
            _feature(NameStyleConverter('d'), depends_on=['b']),
            _feature(NameStyleConverter('e'), depends_on=['d'])
        ]
        self.assertSetEqual(util.origin_trials(features), {'b', 'c', 'd', 'e'})

        features = [
            _feature('a'),
            _feature('b', depends_on=['x', 'y']),
            _feature('c', depends_on=['y', 'z']),
            _feature('x', depends_on=['a']),
            _feature('y', depends_on=['x'], origin_trial_feature_name='y'),
            _feature('z', depends_on=['y'])
        ]
        self.assertSetEqual(util.origin_trials(features), {'b', 'c', 'y', 'z'})
Exemplo n.º 18
0
def _create_inherited_flag_field(property_):
    """
    Create the field used for an inheritance fast path from an independent CSS
    property, and return the Field object.
    """
    name_for_methods = NameStyleConverter(
        property_['name_for_methods']).to_function_name(
            suffix=['is', 'inherited'])
    name_source = NameStyleConverter(name_for_methods)
    return Field(
        'inherited_flag',
        name_for_methods,
        property_name=property_['name'].original,
        type_name='bool',
        wrapper_pointer_name=None,
        field_template='primitive',
        size=1,
        default_value='true',
        custom_copy=False,
        custom_compare=False,
        mutable=False,
        getter_method_name=name_source.to_function_name(),
        setter_method_name=name_source.to_function_name(prefix='set'),
        initial_method_name=name_source.to_function_name(prefix='initial'),
        computed_style_custom_functions=property_[
            "computed_style_custom_functions"],
    )
Exemplo n.º 19
0
 def _get_entry(self, item):
     entry = copy.deepcopy(self._defaults)
     if type(item) is not dict:
         entry["name"] = NameStyleConverter(item)
         return entry
     if "name" not in item:
         raise Exception("Missing name in item: %s" % item)
     if not self.parameters:
         entry.update(item)
         return entry
     assert "name" not in self.parameters, "The parameter 'name' is reserved, use a different name."
     entry["name"] = NameStyleConverter(item.pop("name"))
     # Validate parameters if it's specified.
     for key, value in item.items():
         if key not in self.parameters:
             raise Exception("Unknown parameter: '%s'\nKnown params: %s" %
                             (key, self.parameters.keys()))
         assert self.parameters[key] is not None, \
             "Specification for parameter 'key' cannot be None. Use {} instead."
         self._validate_parameter(self.parameters[key], value)
         entry[key] = value
     return entry
    def __init__(self, name, subgroups, fields):
        self.name = name
        self.subgroups = subgroups
        self.fields = fields
        self.parent = None

        converter = NameStyleConverter(name or '')
        self.type_name = converter.to_class_name(prefix='style', suffix='data')
        self.member_name = converter.to_class_data_member(suffix='data')
        self.num_32_bit_words_for_bit_fields = _num_32_bit_words_for_bit_fields(
            field for field in fields if field.is_bit_field)

        # Recursively get all the fields in the subgroups as well
        self.all_fields = _flatten_list(subgroup.all_fields
                                        for subgroup in subgroups) + fields

        # Ensure that all fields/subgroups on this group link to it
        for field in fields:
            field.group = self

        for subgroup in subgroups:
            subgroup.parent = self
Exemplo n.º 21
0
def main():
    assert len(sys.argv) == 4

    input_file = sys.argv[1]
    output_dir = sys.argv[2]
    bison_exe = sys.argv[3]

    path_to_bison = os.path.split(bison_exe)[0]
    if path_to_bison:
        # Make sure this path is in the path so that it can find its auxiliary
        # binaries (in particular, m4). To avoid other 'm4's being found, insert
        # at head, rather than tail.
        os.environ['PATH'] = path_to_bison + os.pathsep + os.environ['PATH']

    input_name = os.path.basename(input_file)
    assert input_name == 'xpath_grammar.y'
    prefix = {'xpath_grammar.y': 'xpathyy'}[input_name]

    # Output name without directory and extension.
    output_basename = os.path.splitext(input_name)[0] + '_generated'

    output_cc = os.path.join(output_dir, output_basename + '.cc')
    BISON_HEADER_EXT = '.hh'
    original_output_h = os.path.join(output_dir,
                                     output_basename + BISON_HEADER_EXT)

    return_code = subprocess.call(
        [bison_exe, '-d', '-p', prefix, input_file, '-o', output_cc])
    assert return_code == 0
    # If the file doesn't exist, this raise an OSError.
    os.stat(original_output_h)

    # The generated files contain references to the original "foo.hh" for
    # #include and #line. We replace them with "foo.h".
    common_replace_list = [(output_basename + BISON_HEADER_EXT,
                            output_basename + '.h')]

    # Rewrite the generated header with #include guards.
    CLANG_FORMAT_DISABLE_LINE = "// clang-format off"
    output_h = os.path.join(output_dir, output_basename + '.h')
    header_guard = NameStyleConverter(output_h).to_header_guard()
    modify_file(original_output_h, [
        CLANG_FORMAT_DISABLE_LINE,
        '#ifndef %s' % header_guard,
        '#define %s' % header_guard
    ], ['#endif  // %s' % header_guard],
                replace_list=common_replace_list)
    os.rename(original_output_h, output_h)

    modify_file(output_cc, [CLANG_FORMAT_DISABLE_LINE], [],
                replace_list=common_replace_list)
Exemplo n.º 22
0
def v8_value_to_local_cpp_value(interface_name, method, argument, index):
    extended_attributes = argument.extended_attributes
    idl_type = argument.idl_type
    name = NameStyleConverter(argument.name).to_snake_case()
    v8_value = 'info[{index}]'.format(index=index)

    if argument.is_variadic:
        return v8_value_to_local_cpp_variadic_value(argument, index)
    return idl_type.v8_value_to_local_cpp_value(
        extended_attributes,
        v8_value,
        name,
        declare_variable=False,
        use_exception_state=method.returns_promise)
Exemplo n.º 23
0
 def __init__(self, name, source):
     self.name = NameStyleConverter(name).to_snake_case()
     self.header_name = self.name + "_inl.h"
     self.forward_declarations = []
     self.declarations = []
     for line in map(str.strip, source.split("\n")):
         line = re.sub(r"\s{2,}", " ", line).strip()  # Collapse whitespace
         if len(line) == 0:
             continue
         elif line.startswith("class ") or line.startswith("struct "):
             self.forward_declarations.append(line)
         else:
             self.declarations.append(Method(line))
     self.forward_declarations.sort()
Exemplo n.º 24
0
def _find_enum_longest_continuous_segment(property_,
                                          name_to_position_dictionary):
    """Find the longest continuous segment in the list of keywords
    Finding the continuous segment will allows us to do the subtraction
    between keywords so that the distance between 2 keywords in this
    enum is equal to the distance of corresponding keywords in another
    enum.

    Step 1:
        Convert keyword enums into number.
        Sort and find all continuous segment in the list of enums.

    Step 2:
        Get the longest segment.

    Step 3:
        Compose a list of keyword enums and their respective numbers
        in the sorted order.

    Step 4:
        Build the switch case statements of other enums not in the
        segment. Enums in the segment will be computed in default clause.
    """
    property_enum_order = range(len(property_['keywords']))
    css_enum_order = [
        name_to_position_dictionary[x] for x in property_['keywords']
    ]
    enum_pair_list = zip(css_enum_order, property_enum_order)
    enum_segment, enum_pair_list = _find_continuous_segment(enum_pair_list)
    longest_segment = _find_largest_segment(enum_segment)

    enum_tuple_list = []
    for x in enum_pair_list:
        keyword = NameStyleConverter(property_['keywords'][x[1]])
        enum_tuple_list.append((keyword.to_enum_value(), x[1],
                                enum_for_css_keyword(keyword), x[0]))
    return enum_tuple_list, enum_segment, longest_segment
Exemplo n.º 25
0
def v8_value_to_local_cpp_variadic_value(argument, index):
    assert argument.is_variadic
    idl_type = v8_types.native_value_traits_type_name(
        argument.idl_type, argument.extended_attributes, True)
    execution_context_if_needed = ''
    if argument.idl_type.has_string_context:
        execution_context_if_needed = ', bindings::ExecutionContextFromV8Wrappable(impl)'
    assign_expression = 'ToImplArguments<%s>(info, %s, exception_state%s)' % (
        idl_type, index, execution_context_if_needed)
    return {
        'assign_expression': assign_expression,
        'check_expression': 'exception_state.HadException()',
        'cpp_name': NameStyleConverter(argument.name).to_snake_case(),
        'declare_variable': False,
    }
Exemplo n.º 26
0
def argument_set_default_value(argument):
    idl_type = argument.idl_type
    default_value = argument.default_value
    variable_name = NameStyleConverter(argument.name).to_snake_case()
    if not default_value:
        return None
    if idl_type.is_dictionary:
        if argument.default_value.is_null:
            return None
        if argument.default_value.value == '{}':
            return None
        raise Exception('invalid default value for dictionary type')
    if idl_type.is_array_or_sequence_type:
        if default_value.value != '[]':
            raise Exception('invalid default value for sequence type: %s' %
                            default_value.value)
        # Nothing to do when we set an empty sequence as default value, but we
        # need to return non-empty value so that we don't generate method calls
        # without this argument.
        return '/* Nothing to do */'
    if idl_type.is_union_type:
        if argument.default_value.is_null:
            if not idl_type.includes_nullable_type:
                raise Exception(
                    'invalid default value for union type: null for %s' %
                    idl_type.name)
            # Union container objects are "null" initially.
            return '/* null default value */'
        if default_value.value == "{}":
            member_type = idl_type.dictionary_member_type
        elif isinstance(default_value.value, basestring):
            member_type = idl_type.string_member_type
        elif isinstance(default_value.value, (int, float)):
            member_type = idl_type.numeric_member_type
        elif isinstance(default_value.value, bool):
            member_type = idl_type.boolean_member_type
        else:
            member_type = None
        if member_type is None:
            raise Exception('invalid default value for union type: %r for %s' %
                            (default_value.value, idl_type.name))
        member_type_name = (member_type.inner_type.name
                            if member_type.is_nullable else member_type.name)
        return '%s.Set%s(%s)' % (variable_name, member_type_name,
                                 member_type.literal_cpp_value(default_value))
    return '%s = %s' % (variable_name,
                        idl_type.literal_cpp_value(default_value))
Exemplo n.º 27
0
def cpp_value(interface, method, number_of_arguments):
    # Truncate omitted optional arguments
    arguments = method.arguments[:number_of_arguments]
    cpp_arguments = []

    if method.is_constructor:
        call_with_values = interface.extended_attributes.get(
            'ConstructorCallWith')
    else:
        call_with_values = method.extended_attributes.get('CallWith')
    cpp_arguments.extend(v8_utilities.call_with_arguments(call_with_values))

    # Members of IDL partial interface definitions are implemented in C++ as
    # static member functions, which for instance members (non-static members)
    # take *impl as their first argument
    if ('PartialInterfaceImplementedAs' in method.extended_attributes
            and not method.is_static):
        cpp_arguments.append('*impl')
    for argument in arguments:
        variable_name = NameStyleConverter(argument.name).to_snake_case()
        if argument.idl_type.base_type == 'SerializedScriptValue':
            cpp_arguments.append('std::move(%s)' % variable_name)
        else:
            cpp_arguments.append(variable_name)

    if ('RaisesException' in method.extended_attributes
            or (method.is_constructor and has_extended_attribute_value(
                interface, 'RaisesException', 'Constructor'))):
        cpp_arguments.append('exception_state')

    # If a method returns an IDL dictionary or union type, the return value is
    # passed as an argument to impl classes.
    idl_type = method.idl_type
    if idl_type and idl_type.use_output_parameter_for_result:
        cpp_arguments.append('result')

    if method.name == 'Constructor':
        base_name = 'Create'
    elif method.name == 'NamedConstructor':
        base_name = 'CreateForJSConstructor'
    else:
        base_name = v8_utilities.cpp_name(method)

    cpp_method_name = v8_utilities.scoped_name(interface, method, base_name)
    return '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))
    def __init__(self, json5_file_path, output_dir):
        super(MakeElementTypeHelpersWriter,
              self).__init__(json5_file_path, output_dir)

        self.namespace = self.json5_file.metadata['namespace'].strip('"')
        self.fallback_interface = self.json5_file.metadata[
            'fallbackInterfaceName'].strip('"')

        assert self.namespace, 'A namespace is required.'

        basename = self.namespace.lower() + '_element_type_helpers'
        self._outputs = {
            (basename + '.h'): self.generate_helper_header,
            (basename + '.cc'): self.generate_helper_implementation,
        }

        base_element_header = 'third_party/blink/renderer/core/{}/{}_element.h'.format(
            self.namespace.lower(),
            NameStyleConverter(self.namespace).to_snake_case())
        self._template_context = {
            'base_element_header': base_element_header,
            'cpp_namespace': self.namespace.lower() + '_names',
            'input_files': self._input_files,
            'namespace': self.namespace,
            'tags': self.json5_file.name_dictionaries,
            'elements': set(),
        }

        tags = self._template_context['tags']
        elements = self._template_context['elements']
        interface_counts = defaultdict(int)
        for tag in tags:
            tag['interface'] = self._interface(tag)
            interface_counts[tag['interface']] += 1
            tag['js_interface'] = tag['interface']
            if tag['JSInterfaceName']:
                tag['js_interface'] = tag['JSInterfaceName']
            elements.add(tag['js_interface'])

        for tag in tags:
            tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1
                                       or tag['interface']
                                       == self.fallback_interface)
Exemplo n.º 29
0
def relative_dest(fs, filename):
    """Returns a destination path string for given filename.

    |filename| is a path relative to third_party/WebKit, and the resultant path
    is relative to third_party/blink.
    """
    dest = None
    if filename.startswith('Source'):
        dest = re.sub(r'^Source', 'renderer', filename)
    elif filename.startswith('common') or filename.startswith('public'):
        dest = filename
    else:
        raise ValueError(
            '|filename| must start with "common", "public", or "Source": %s' %
            filename)
    if filename.endswith(
        ('.h', '.cpp', '.mm', '.idl', '.typemap', '.proto', 'Settings.json5')):
        dirname, basename = fs.split(dest)
        basename, ext = fs.splitext(basename)
        # Skip some inspector-related files. #includes for these files are
        # generated by a script outside of Blink.
        if (re.match(r'Inspector.*Agent', basename)
                or basename.startswith('AdTracker')
                or basename == 'InspectorTraceEvents'
                or basename == 'PerformanceMonitor'
                or basename == 'PlatformTraceEventsAgent'):
            return dest
        if filename.endswith('.cpp'):
            ext = '.cc'
        # WebKit.h should be renamed to blink.h.
        if basename == 'WebKit' and ext == '.h':
            basename = 'blink'
        if basename.lower() != basename:
            basename = NameStyleConverter(basename).to_snake_case()
        return fs.join(dirname, basename + ext)
    return dest
Exemplo n.º 30
0
def attribute_context(interface, attribute, interfaces, component_info):
    """Creates a Jinja template context for an attribute of an interface.

    Args:
        interface: An interface which |attribute| belongs to
        attribute: An attribute to create the context for
        interfaces: A dict which maps an interface name to the definition
            which can be referred if needed
        component_info: A dict containing component wide information

    Returns:
        A Jinja template context for |attribute|
    """

    idl_type = attribute.idl_type
    base_idl_type = idl_type.base_type
    extended_attributes = attribute.extended_attributes

    idl_type.add_includes_for_type(extended_attributes)
    if idl_type.enum_values:
        includes.add('core/inspector/console_message.h')
        includes.add('platform/heap/heap.h')

    # [CheckSecurity]
    is_cross_origin = 'CrossOrigin' in extended_attributes
    is_check_security_for_receiver = (has_extended_attribute_value(
        interface, 'CheckSecurity', 'Receiver') and is_cross_origin)
    is_check_security_for_return_value = (has_extended_attribute_value(
        attribute, 'CheckSecurity', 'ReturnValue'))
    if is_check_security_for_receiver or is_check_security_for_return_value:
        includes.add('bindings/core/v8/binding_security.h')
    if is_check_security_for_return_value:
        includes.add('core/frame/web_feature.h')
        includes.add('platform/instrumentation/use_counter.h')
    # [CrossOrigin]
    if has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'):
        includes.add('platform/bindings/v8_cross_origin_callback_info.h')
    # [Constructor]
    # TODO(yukishiino): Constructors are much like methods although constructors
    # are not methods.  Constructors must be data-type properties, and we can
    # support them as a kind of methods.
    constructor_type = idl_type.constructor_type_name if is_constructor_attribute(
        attribute) else None
    # [CEReactions]
    is_ce_reactions = 'CEReactions' in extended_attributes
    if is_ce_reactions:
        includes.add('core/html/custom/ce_reactions_scope.h')
    # [CustomElementCallbacks], [Reflect]
    is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes
    is_reflect = 'Reflect' in extended_attributes
    # [ReflectOnly]
    reflect_only = extended_attribute_value_as_list(attribute, 'ReflectOnly')
    if reflect_only:
        reflect_only = map(
            lambda v: cpp_content_attribute_value_name(interface, v),
            reflect_only)
    if is_custom_element_callbacks or is_reflect:
        includes.add('core/html/custom/v0_custom_element_processing_stack.h')
    # [PerWorldBindings]
    if 'PerWorldBindings' in extended_attributes:
        assert idl_type.is_wrapper_type or 'LogActivity' in \
            extended_attributes, \
            '[PerWorldBindings] should only be used with wrapper types: %s.%s' % \
            (interface.name, attribute.name)
    # [SaveSameObject]
    is_save_same_object = ('SameObject' in attribute.extended_attributes and
                           'SaveSameObject' in attribute.extended_attributes)

    # [StringContext]
    if idl_type.has_string_context:
        includes.add('bindings/core/v8/generated_code_helper.h')

    # [CachedAccessor]
    is_cached_accessor = 'CachedAccessor' in extended_attributes

    # [LenientSetter]
    is_lenient_setter = 'LenientSetter' in extended_attributes

    # [CachedAttribute]
    cached_attribute_validation_method = extended_attributes.get(
        'CachedAttribute')

    keep_alive_for_gc = is_keep_alive_for_gc(interface, attribute)

    does_generate_getter = (not has_custom_getter(attribute)
                            and not constructor_type)
    does_generate_setter = (
        has_setter(interface, attribute)
        and not (has_custom_setter(attribute) or is_lenient_setter))

    use_private_property_in_getter = (does_generate_getter
                                      and (cached_attribute_validation_method
                                           or is_save_same_object
                                           or keep_alive_for_gc))
    use_private_property_in_setter = (does_generate_setter
                                      and cached_attribute_validation_method)
    private_property_is_shared_between_getter_and_setter = (
        use_private_property_in_getter and use_private_property_in_setter)

    does_use_private_property = (use_private_property_in_getter
                                 or use_private_property_in_setter
                                 or is_cached_accessor)
    if does_use_private_property:
        includes.add('platform/bindings/v8_private_property.h')

    # [LogActivity]
    if 'LogActivity' in extended_attributes:
        includes.add('platform/bindings/v8_per_context_data.h')

    # [DeprecateAs], [MeasureAs]
    deprecate_as = v8_utilities.deprecate_as(attribute)
    measure_as = v8_utilities.measure_as(attribute, interface)

    # [HighEntropy]
    high_entropy = v8_utilities.high_entropy(attribute)

    is_lazy_data_attribute = \
        (constructor_type and not (measure_as or deprecate_as)) or \
        (str(idl_type) == 'Window' and attribute.name in ('frames', 'self', 'window'))

    runtime_features = component_info['runtime_enabled_features']

    internal_name = cpp_encoded_property_name(attribute)

    cpp_type = idl_type.cpp_type
    if idl_type.is_explicit_nullable:
        cpp_type = v8_types.cpp_template_type('base::Optional', cpp_type)

    context = {
        # [ActivityLogging]
        'activity_logging_world_list_for_getter':
        v8_utilities.activity_logging_world_list(attribute, 'Getter'),
        # [ActivityLogging]
        'activity_logging_world_list_for_setter':
        v8_utilities.activity_logging_world_list(attribute, 'Setter'),
        # [ActivityLogging]
        'activity_logging_world_check':
        v8_utilities.activity_logging_world_check(attribute),
        'cached_accessor_name':
        'k%s%s' % (interface.name, attribute.name.capitalize()),
        'cached_attribute_validation_method':
        cached_attribute_validation_method,
        'camel_case_name':
        NameStyleConverter(internal_name).to_upper_camel_case(),
        'constructor_type':
        constructor_type,
        'context_enabled_feature_name':
        v8_utilities.context_enabled_feature_name(attribute),
        'cpp_name': cpp_name(attribute),
        'cpp_type': cpp_type,
        'cpp_type_initializer': idl_type.cpp_type_initializer,
        'deprecate_as': deprecate_as,
        'does_generate_getter': does_generate_getter,
        'does_generate_setter': does_generate_setter,
        'enum_type': idl_type.enum_type,
        'enum_values': idl_type.enum_values,
        # [Exposed]
        'exposed_test':
        v8_utilities.exposed(attribute, interface),
        'getter_has_no_side_effect':
        has_extended_attribute_value(attribute, 'Affects', 'Nothing'),
        'has_cross_origin_getter':
            has_extended_attribute_value(attribute, 'CrossOrigin', None) or
            has_extended_attribute_value(attribute, 'CrossOrigin', 'Getter'),
        'has_cross_origin_setter':
        has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'),
        'has_custom_getter': has_custom_getter(attribute),
        'has_custom_setter': has_custom_setter(attribute),
        'has_promise_type': idl_type.name == 'Promise',
        'has_setter': has_setter(interface, attribute),
        'high_entropy': high_entropy,
        'idl_type': str(idl_type),
        'is_cached_accessor': is_cached_accessor,
        'is_call_with_execution_context':
        has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'),
        'is_call_with_script_state':
        has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'),
        'is_ce_reactions': is_ce_reactions,
        'is_check_security_for_receiver': is_check_security_for_receiver,
        'is_check_security_for_return_value':
        is_check_security_for_return_value,
        'is_custom_element_callbacks': is_custom_element_callbacks,
        # TODO(yukishiino): Make all DOM attributes accessor-type properties.
        'is_data_type_property': is_data_type_property(interface, attribute),
        'is_getter_raises_exception':  # [RaisesException]
            'RaisesException' in extended_attributes and
            extended_attributes['RaisesException'] in (None, 'Getter'),
        'is_keep_alive_for_gc': keep_alive_for_gc,
        'is_lazy_data_attribute': is_lazy_data_attribute,
        'is_lenient_setter': is_lenient_setter,
        'is_lenient_this': 'LegacyLenientThis' in extended_attributes,
        'is_nullable': idl_type.is_nullable,
        'is_explicit_nullable': idl_type.is_explicit_nullable,
        'is_named_constructor': is_named_constructor_attribute(attribute),
        'is_partial_interface_member':
            'PartialInterfaceImplementedAs' in extended_attributes,
        'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
        'is_put_forwards': 'PutForwards' in extended_attributes,
        'is_read_only': attribute.is_read_only,
        'is_reflect': is_reflect,
        'is_replaceable': 'Replaceable' in attribute.extended_attributes,
        'is_save_same_object': is_save_same_object,
        'is_static': attribute.is_static,
        'is_url': 'URL' in extended_attributes,
        'is_unforgeable': is_unforgeable(attribute),
        'measure_as': measure_as,
        'name': attribute.name,
        'on_instance': v8_utilities.on_instance(interface, attribute),
        'on_interface': v8_utilities.on_interface(interface, attribute),
        'on_prototype': v8_utilities.on_prototype(interface, attribute),
        # [RuntimeEnabled] for origin trial
        'origin_trial_feature_name':
            v8_utilities.origin_trial_feature_name(attribute, runtime_features),
        'private_property_is_shared_between_getter_and_setter':
        private_property_is_shared_between_getter_and_setter,
        'property_attributes': property_attributes(interface, attribute),
        'reflect_empty': cpp_content_attribute_value_name(
            interface, extended_attributes.get('ReflectEmpty')),
        'reflect_invalid': cpp_content_attribute_value_name(
            interface, extended_attributes.get('ReflectInvalid', '')),
        'reflect_missing': cpp_content_attribute_value_name(
            interface, extended_attributes.get('ReflectMissing')),
        'reflect_only': reflect_only,
        # [RuntimeEnabled] if not in origin trial
        'runtime_enabled_feature_name':
        v8_utilities.runtime_enabled_feature_name(attribute, runtime_features),
        # [SecureContext]
        'secure_context_test': v8_utilities.secure_context(attribute, interface),
        'use_output_parameter_for_result': idl_type.use_output_parameter_for_result,
        'world_suffixes': (
            ['', 'ForMainWorld']
            if 'PerWorldBindings' in extended_attributes
            else ['']),  # [PerWorldBindings]
    }

    if not has_custom_getter(attribute):
        getter_context(interface, attribute, context)
    if not has_custom_setter(attribute) and has_setter(interface, attribute):
        setter_context(interface, attribute, interfaces, context)

    # [RuntimeCallStatsCounter]
    runtime_call_stats_context(interface, attribute, context)

    # [CrossOrigin] is incompatible with a number of other attributes, so check
    # for them here.
    if is_cross_origin:
        if context['has_cross_origin_setter'] and context['has_custom_setter']:
            raise Exception(
                '[CrossOrigin] and [Custom] are incompatible on the same setter: %s.%s',
                interface.name, attribute.name)
        if context['is_per_world_bindings']:
            raise Exception(
                '[CrossOrigin] and [PerWorldBindings] are incompatible: %s.%s',
                interface.name, attribute.name)
        if context['constructor_type']:
            raise Exception(
                '[CrossOrigin] cannot be used for constructors: %s.%s',
                interface.name, attribute.name)

    return context