Пример #1
0
    def __init__(self, json5_file_paths):
        super(MakeQualifiedNamesWriter, self).__init__(None)
        self._input_files = copy.copy(json5_file_paths)
        assert len(json5_file_paths) <= 2, 'MakeQualifiedNamesWriter requires at most 2 in files, got %d.' % len(json5_file_paths)

        if len(json5_file_paths) == 2:
            self.tags_json5_file = Json5File.load_from_files(
                [json5_file_paths.pop(0)], self.default_metadata, self.default_parameters)
        else:
            self.tags_json5_file = None

        self.attrs_json5_file = Json5File.load_from_files([json5_file_paths.pop()], self.default_metadata, self.default_parameters)

        self.namespace = self._metadata('namespace')

        namespace_prefix = self._metadata('namespacePrefix') or self.namespace.lower()
        namespace_uri = self._metadata('namespaceURI')

        use_namespace_for_attrs = self.attrs_json5_file.metadata['attrsNullNamespace'] is None

        self._outputs = {
            (self.namespace + "Names.h"): self.generate_header,
            (self.namespace + "Names.cpp"): self.generate_implementation,
        }
        self._template_context = {
            'attrs': self.attrs_json5_file.name_dictionaries,
            'export': self._metadata('export'),
            'input_files': self._input_files,
            'namespace': self.namespace,
            'namespace_prefix': namespace_prefix,
            'namespace_uri': namespace_uri,
            'tags': self.tags_json5_file.name_dictionaries if self.tags_json5_file else [],
            'use_namespace_for_attrs': use_namespace_for_attrs,
        }
Пример #2
0
    def __init__(self, json5_file_paths, output_dir):
        super(MakeQualifiedNamesWriter, self).__init__(None, output_dir)
        self._input_files = copy.copy(json5_file_paths)
        assert len(json5_file_paths) <= 3, 'MakeQualifiedNamesWriter requires at most 3 in files, got %d.' % len(json5_file_paths)

        # Input files are in a strict order with more optional files *first*:
        # 1) ARIA properties
        # 2) Tags
        # 3) Attributes

        if len(json5_file_paths) >= 3:
            aria_json5_filename = json5_file_paths.pop(0)
            self.aria_reader = ARIAReader(aria_json5_filename)
        else:
            self.aria_reader = None

        if len(json5_file_paths) >= 2:
            tags_json5_filename = json5_file_paths.pop(0)
            self.tags_json5_file = Json5File.load_from_files([tags_json5_filename], self.default_metadata, self.default_parameters)
        else:
            self.tags_json5_file = None

        self.attrs_json5_file = Json5File.load_from_files([json5_file_paths.pop()], self.default_metadata, self.default_parameters)

        if self.aria_reader is not None:
            self.attrs_json5_file.merge_from(self.aria_reader.attributes_list())

        self.namespace = self._metadata('namespace')
        cpp_namespace = self.namespace.lower() + '_names'
        namespace_prefix = self._metadata('namespacePrefix') or 'k'
        # TODO(tkent): Remove the following branch.  crbug.com/889726
        if self.namespace in ('HTML', 'MathML', 'SVG'):
            cpp_namespace = self.namespace + 'Names'
            MakeQualifiedNamesWriter.filters['symbol'] = _legacy_symbol
            namespace_prefix = self._metadata('namespacePrefix') or self.namespace.lower()

        namespace_uri = self._metadata('namespaceURI')
        use_namespace_for_attrs = self.attrs_json5_file.metadata['attrsNullNamespace'] is None

        self._outputs = {
            (self.namespace.lower() + "_names.h"): self.generate_header,
            (self.namespace.lower() + "_names.cc"): self.generate_implementation,
        }
        qualified_header = self._relative_output_dir + self.namespace.lower() + '_names.h'
        self._template_context = {
            'attrs': self.attrs_json5_file.name_dictionaries,
            'cpp_namespace': cpp_namespace,
            'export': self._metadata('export'),
            'header_guard': self.make_header_guard(qualified_header),
            'input_files': self._input_files,
            'namespace': self.namespace,
            'namespace_prefix': namespace_prefix,
            'namespace_uri': namespace_uri,
            'tags': self.tags_json5_file.name_dictionaries if self.tags_json5_file else [],
            'this_include_path': qualified_header,
            'use_namespace_for_attrs': use_namespace_for_attrs,
        }
 def test_valid_dict_value_parse(self):
     actual = Json5File.load_from_files([self.path_of_test_file(
         'json5_generator_valid_dict_value.json5')]).name_dictionaries
     expected = [
         {'name': 'item1', 'param1': {'keys': 'valid', 'random': 'values'}},
         {'name': 'item2', 'param1': {'random': 'values', 'default': 'valid'}}
     ]
     self.assertEqual(len(actual), len(expected))
     for exp, act in zip(expected, actual):
         self.assertDictEqual(exp['param1'], act['param1'])
Пример #4
0
 def make_runtime_features_dict():
     input_filename = os.path.join(TEST_INPUT_DIRECTORY,
                                   'runtime_enabled_features.json5')
     json5_file = Json5File.load_from_files([input_filename])
     features_map = {}
     for feature in json5_file.name_dictionaries:
         features_map[str(feature['name'])] = {
             'in_origin_trial': feature['in_origin_trial']
         }
     return features_map
Пример #5
0
    def __init__(self, json5_file_paths):
        super(CSSPropertyAPIWriter, self).__init__(json5_file_paths[0])
        # TODO(aazzam): Move the logic for loading CSSPropertyAPIMethods.json5 into a new class APIMethodsWriter().
        assert len(json5_file_paths) == 2,\
            'CSSPropertyAPIWriter requires 2 input json5 files files, got {}.'.format(len(json5_file_paths))

        self.css_property_api_methods = Json5File.load_from_files(
            [json5_file_paths[1]], {}, {})

        self._outputs = {
            'CSSPropertyDescriptor.cpp': self.generate_property_descriptor_cpp,
            'CSSPropertyDescriptor.h': self.generate_property_descriptor_h,
            'CSSPropertyAPI.h': self.generate_property_api,
        }

        # Stores a map of API method name -> (return_type, parameters)
        self.all_api_methods = {}
        # Stores an ordered list of all API method names. This must match the
        # order they appear in the Descriptor object.
        self.ordered_api_method_names = []
        for api_method in self.css_property_api_methods.name_dictionaries:
            self.ordered_api_method_names.append(api_method['name'])
            # TODO(shend): wrap description to 72 chars
            self.all_api_methods[api_method['name']] = ApiMethod(
                return_type=api_method['return_type'],
                parameters=api_method['parameters'],
                description=api_method['description'],
            )

        # Temporary map of API classname to list of propertyIDs that the API class is for.
        properties_for_class = defaultdict(list)
        # Map of API classname to list of methods implemented by that class.
        self.methods_for_classes = defaultdict(list)
        for property_ in self.properties().values():
            if property_['api_class'] is None:
                continue
            classname = get_classname(property_)
            properties_for_class[classname].append(property_['property_id'])
            # For api_classes that contain multiple properties, combine all implemented properties.
            # This list contains duplicate entries, but is only used to check if a method is
            # implemented for an api_class.
            self.methods_for_classes[classname] += property_['api_methods']
            self._outputs[classname +
                          '.h'] = self.generate_property_api_h_builder(
                              classname)

        # Stores a list of classes with elements (index, classname, [propertyIDs, ..], [api_methods, ...]).
        self._api_classes = []
        for i, classname in enumerate(properties_for_class.keys()):
            self._api_classes.append(
                ApiClass(
                    index=i + 1,
                    classname=classname,
                    property_ids=properties_for_class[classname],
                    methods_for_class=self.methods_for_classes[classname]))
Пример #6
0
    def __init__(self, json5_file_paths):
        super(CSSPropertyAPIWriter, self).__init__([json5_file_paths[0]])
        # TODO(aazzam): Move the logic for loading CSSPropertyAPIMethods.json5 into a new class APIMethodsWriter().
        assert len(json5_file_paths) == 2,\
            'CSSPropertyAPIWriter requires 2 input json5 files files, got {}.'.format(len(json5_file_paths))

        self.css_property_api_methods = Json5File.load_from_files(
            [json5_file_paths[1]])

        self._outputs = {
            'CSSPropertyDescriptor.cpp': self.generate_property_descriptor_cpp,
            'CSSPropertyDescriptor.h': self.generate_property_descriptor_h,
        }

        # Stores a map of API method name -> (return_type, parameters)
        self.all_api_methods = {}
        # Stores an ordered list of all API method names. This must match the
        # order they appear in the Descriptor object.
        self.ordered_api_method_names = []
        for api_method in self.css_property_api_methods.name_dictionaries:
            self.ordered_api_method_names.append(api_method['name'])
            # TODO(shend): wrap description to 72 chars
            self.all_api_methods[api_method['name']] = ApiMethod(
                return_type=api_method['return_type'],
                parameters=api_method['parameters'],
                description=api_method['description'],
            )

        # Temporary maps of API classname to list of propertyIDs and corresponding
        # enum values that the API class is for.
        properties_for_class = defaultdict(list)
        property_enums_for_class = defaultdict(list)
        # Map of API classname to list of methods implemented by that class.
        self.methods_for_classes = defaultdict(list)
        for property_ in self.properties().values():
            if property_['api_class'] is None:
                continue
            classname = get_classname(property_)
            properties_for_class[classname].append(property_['property_id'])
            property_enums_for_class[classname].append(property_['enum_value'])
            # For api_classes that contain multiple properties, combine all implemented properties.
            # This list contains duplicate entries, but is only used to check if a method is
            # implemented for an api_class.
            self.methods_for_classes[classname] += property_['api_methods']
            self._outputs[classname +
                          '.h'] = self.generate_property_api_h_builder(
                              classname, property_['name'])

        # Stores a list of classes with elements (index, classname, [propertyIDs, ..], [api_methods, ...]).
        self._api_classes = []
        for i, classname in enumerate(properties_for_class.keys()):
            self._api_classes.append(
                ApiClass(
                    index=i + 1,
                    classname=classname,
                    property_ids=properties_for_class[classname],
                    methods_for_class=self.methods_for_classes[classname]))

        # Build a table converting id (including aliases) to api class descriptors
        self._invalid_descriptor_index = 0
        # Initialize the whole thing to the invalid descriptor to handle gaps
        num_indices = self.last_unresolved_property_id + 1
        self._descriptor_indices = dict.fromkeys(xrange(num_indices), {
            'id': self._invalid_descriptor_index,
            'api': None
        })
        # Now populate all entries for which there exists a class, i.e. that aren't gaps
        for api_class in self._api_classes:
            for property_enum in property_enums_for_class[api_class.classname]:
                self._descriptor_indices[property_enum] = {
                    'id': api_class.index,
                    'api': api_class.classname
                }
 def test_key_not_in_valid_keys(self):
     with self.assertRaises(Exception):
         Json5File.load_from_files([self.path_of_test_file('json5_generator_invalid_key.json5')])
 def test_no_valid_keys(self):
     with self.assertRaises(AssertionError):
         Json5File.load_from_files([self.path_of_test_file('json5_generator_no_valid_keys.json5')])