1#!/usr/bin/env python 2# Copyright (C) 2013 Google Inc. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: 7# 8# * Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# * Redistributions in binary form must reproduce the above 11# copyright notice, this list of conditions and the following disclaimer 12# in the documentation and/or other materials provided with the 13# distribution. 14# * Neither the name of Google Inc. nor the names of its 15# contributors may be used to endorse or promote products derived from 16# this software without specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30import sys 31from collections import defaultdict 32 33import json5_generator 34import template_expander 35import name_utilities 36 37from make_qualified_names import MakeQualifiedNamesWriter 38 39 40class MakeElementFactoryWriter(MakeQualifiedNamesWriter): 41 default_parameters = { 42 'JSInterfaceName': {}, 43 'Conditional': {}, 44 'constructorNeedsCreateElementFlags': {}, 45 'interfaceHeaderDir': {}, 46 'interfaceName': {}, 47 'noConstructor': {}, 48 'noTypeHelpers': {}, 49 'runtimeEnabled': {}, 50 } 51 default_metadata = dict( 52 MakeQualifiedNamesWriter.default_metadata, **{ 53 'fallbackInterfaceName': '', 54 'fallbackJSInterfaceName': '', 55 }) 56 filters = MakeQualifiedNamesWriter.filters 57 58 def __init__(self, json5_file_paths, output_dir): 59 super(MakeElementFactoryWriter, self).__init__(json5_file_paths, 60 output_dir) 61 62 basename = self.namespace.lower() + '_element_factory' 63 self._outputs.update({ 64 (basename + '.h'): 65 self.generate_factory_header, 66 (basename + '.cc'): 67 self.generate_factory_implementation, 68 }) 69 70 fallback_interface = self.tags_json5_file.metadata[ 71 'fallbackInterfaceName'].strip('"') 72 fallback_js_interface = self.tags_json5_file.metadata[ 73 'fallbackJSInterfaceName'].strip('"') or fallback_interface 74 75 interface_counts = defaultdict(int) 76 tags = self._template_context['tags'] 77 for tag in tags: 78 tag['has_js_interface'] = self._has_js_interface(tag) 79 tag['js_interface'] = self._js_interface(tag) 80 tag['interface'] = self._interface(tag) 81 tag['interface_header'] = '%s/%s.h' % (self._interface_header_dir( 82 tag), self.get_file_basename(tag['interface'])) 83 interface_counts[tag['interface']] += 1 84 85 for tag in tags: 86 tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1 87 or 88 tag['interface'] == fallback_interface) 89 90 self._template_context.update({ 91 'fallback_interface': 92 fallback_interface, 93 'fallback_interface_header': 94 self.get_file_basename(fallback_interface) + '.h', 95 'fallback_js_interface': 96 fallback_js_interface, 97 'input_files': 98 self._input_files, 99 }) 100 101 @template_expander.use_jinja( 102 'templates/element_factory.h.tmpl', filters=filters) 103 def generate_factory_header(self): 104 return self._template_context 105 106 @template_expander.use_jinja( 107 'templates/element_factory.cc.tmpl', filters=filters) 108 def generate_factory_implementation(self): 109 return self._template_context 110 111 def _interface(self, tag): 112 if tag['interfaceName']: 113 return tag['interfaceName'] 114 name = tag['name'].to_upper_camel_case() 115 # FIXME: We shouldn't hard-code HTML here. 116 if name == 'HTML': 117 name = 'Html' 118 return '%s%sElement' % (self.namespace, name) 119 120 def _js_interface(self, tag): 121 if tag['JSInterfaceName']: 122 return tag['JSInterfaceName'] 123 return self._interface(tag) 124 125 def _has_js_interface(self, tag): 126 return not tag['noConstructor'] and self._js_interface(tag) != ( 127 '%sElement' % self.namespace) 128 129 def _interface_header_dir(self, tag): 130 if tag['interfaceHeaderDir']: 131 return tag['interfaceHeaderDir'] 132 return 'third_party/blink/renderer/core/' + self.namespace.lower() 133 134 135if __name__ == "__main__": 136 json5_generator.Maker(MakeElementFactoryWriter).main() 137