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 in_generator 34import template_expander 35import name_utilities 36 37from make_qualified_names import MakeQualifiedNamesWriter 38 39 40class MakeElementFactoryWriter(MakeQualifiedNamesWriter): 41 defaults = dict(MakeQualifiedNamesWriter.default_parameters, **{ 42 'JSInterfaceName': None, 43 'Conditional': None, 44 'constructorNeedsCreatedByParser': None, 45 'constructorNeedsFormElement': None, 46 'interfaceName': None, 47 'noConstructor': None, 48 'noTypeHelpers': None, 49 'runtimeEnabled': None, 50 }) 51 default_parameters = dict(MakeQualifiedNamesWriter.default_parameters, **{ 52 'fallbackInterfaceName': '', 53 'fallbackJSInterfaceName': '', 54 }) 55 filters = MakeQualifiedNamesWriter.filters 56 57 def __init__(self, in_file_paths): 58 super(MakeElementFactoryWriter, self).__init__(in_file_paths) 59 60 # FIXME: When we start using these element factories, we'll want to 61 # remove the "new" prefix and also have our base class generate 62 # *Names.h and *Names.cpp. 63 self._outputs.update({ 64 (self.namespace + 'ElementFactory.h'): self.generate_factory_header, 65 (self.namespace + 'ElementFactory.cpp'): self.generate_factory_implementation, 66 }) 67 68 fallback_interface = self.tags_in_file.parameters['fallbackInterfaceName'].strip('"') 69 fallback_js_interface = self.tags_in_file.parameters['fallbackJSInterfaceName'].strip('"') or fallback_interface 70 71 interface_counts = defaultdict(int) 72 tags = self._template_context['tags'] 73 for tag in tags: 74 tag['has_js_interface'] = self._has_js_interface(tag) 75 tag['js_interface'] = self._js_interface(tag) 76 tag['interface'] = self._interface(tag) 77 interface_counts[tag['interface']] += 1 78 79 for tag in tags: 80 tag['multipleTagNames'] = (interface_counts[tag['interface']] > 1 or tag['interface'] == fallback_interface) 81 82 self._template_context.update({ 83 'fallback_interface': fallback_interface, 84 'fallback_js_interface': fallback_js_interface, 85 }) 86 87 @template_expander.use_jinja('ElementFactory.h.tmpl', filters=filters) 88 def generate_factory_header(self): 89 return self._template_context 90 91 @template_expander.use_jinja('ElementFactory.cpp.tmpl', filters=filters) 92 def generate_factory_implementation(self): 93 return self._template_context 94 95 def _interface(self, tag): 96 if tag['interfaceName']: 97 return tag['interfaceName'] 98 name = name_utilities.upper_first(tag['name']) 99 # FIXME: We shouldn't hard-code HTML here. 100 if name == 'HTML': 101 name = 'Html' 102 dash = name.find('-') 103 while dash != -1: 104 name = name[:dash] + name[dash + 1].upper() + name[dash + 2:] 105 dash = name.find('-') 106 return '%s%sElement' % (self.namespace, name) 107 108 def _js_interface(self, tag): 109 if tag['JSInterfaceName']: 110 return tag['JSInterfaceName'] 111 return self._interface(tag) 112 113 def _has_js_interface(self, tag): 114 return not tag['noConstructor'] and self._js_interface(tag) != ('%sElement' % self.namespace) 115 116 117if __name__ == "__main__": 118 in_generator.Maker(MakeElementFactoryWriter).main(sys.argv) 119