| OLD | NEW |
| (Empty) |
| 1 # Copyright (C) 2013 Google Inc. All rights reserved. | |
| 2 # | |
| 3 # Redistribution and use in source and binary forms, with or without | |
| 4 # modification, are permitted provided that the following conditions are | |
| 5 # met: | |
| 6 # | |
| 7 # * Redistributions of source code must retain the above copyright | |
| 8 # notice, this list of conditions and the following disclaimer. | |
| 9 # * Redistributions in binary form must reproduce the above | |
| 10 # copyright notice, this list of conditions and the following disclaimer | |
| 11 # in the documentation and/or other materials provided with the | |
| 12 # distribution. | |
| 13 # * Neither the name of Google Inc. nor the names of its | |
| 14 # contributors may be used to endorse or promote products derived from | |
| 15 # this software without specific prior written permission. | |
| 16 # | |
| 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 28 | |
| 29 """Functions shared by various parts of the code generator. | |
| 30 | |
| 31 Extends IdlTypeBase type with |enum_validation_expression| property. | |
| 32 | |
| 33 Design doc: http://www.chromium.org/developers/design-documents/idl-compiler | |
| 34 """ | |
| 35 | |
| 36 import re | |
| 37 | |
| 38 from idl_types import IdlTypeBase | |
| 39 import idl_types | |
| 40 from v8_globals import includes | |
| 41 import v8_types | |
| 42 | |
| 43 ACRONYMS = [ | |
| 44 'CSSOM', # must come *before* CSS to match full acronym | |
| 45 'CSS', | |
| 46 'HTML', | |
| 47 'IME', | |
| 48 'JS', | |
| 49 'URL', | |
| 50 'WOFF', | |
| 51 'XML', | |
| 52 ] | |
| 53 | |
| 54 | |
| 55 ################################################################################ | |
| 56 # Extended attribute parsing | |
| 57 ################################################################################ | |
| 58 | |
| 59 def extended_attribute_value_contains(extended_attribute_value, key): | |
| 60 return (extended_attribute_value == key or | |
| 61 (isinstance(extended_attribute_value, list) and | |
| 62 key in extended_attribute_value)) | |
| 63 | |
| 64 | |
| 65 def has_extended_attribute(definition_or_member, extended_attribute_list): | |
| 66 return any(extended_attribute in definition_or_member.extended_attributes | |
| 67 for extended_attribute in extended_attribute_list) | |
| 68 | |
| 69 | |
| 70 def has_extended_attribute_value(definition_or_member, name, value): | |
| 71 extended_attributes = definition_or_member.extended_attributes | |
| 72 return (name in extended_attributes and | |
| 73 extended_attribute_value_contains(extended_attributes[name], value)) | |
| 74 | |
| 75 | |
| 76 def extended_attribute_value_as_list(definition_or_member, name): | |
| 77 extended_attributes = definition_or_member.extended_attributes | |
| 78 if name not in extended_attributes: | |
| 79 return None | |
| 80 value = extended_attributes[name] | |
| 81 if isinstance(value, list): | |
| 82 return value | |
| 83 return [value] | |
| 84 | |
| 85 | |
| 86 ################################################################################ | |
| 87 # String handling | |
| 88 ################################################################################ | |
| 89 | |
| 90 def capitalize(name): | |
| 91 """Capitalize first letter or initial acronym (used in setter names).""" | |
| 92 for acronym in ACRONYMS: | |
| 93 if name.startswith(acronym.lower()): | |
| 94 return name.replace(acronym.lower(), acronym) | |
| 95 return name[0].upper() + name[1:] | |
| 96 | |
| 97 | |
| 98 def strip_suffix(string, suffix): | |
| 99 if not suffix or not string.endswith(suffix): | |
| 100 return string | |
| 101 return string[:-len(suffix)] | |
| 102 | |
| 103 | |
| 104 def uncapitalize(name): | |
| 105 """Uncapitalizes first letter or initial acronym (used in method names). | |
| 106 | |
| 107 E.g., 'SetURL' becomes 'setURL', but 'URLFoo' becomes 'urlFoo'. | |
| 108 """ | |
| 109 for acronym in ACRONYMS: | |
| 110 if name.startswith(acronym): | |
| 111 return name.replace(acronym, acronym.lower()) | |
| 112 return name[0].lower() + name[1:] | |
| 113 | |
| 114 | |
| 115 ################################################################################ | |
| 116 # C++ | |
| 117 ################################################################################ | |
| 118 | |
| 119 def enum_validation_expression(idl_type): | |
| 120 # FIXME: Add IdlEnumType, move property to derived type, and remove this che
ck | |
| 121 if not idl_type.is_enum: | |
| 122 return None | |
| 123 return ' || '.join(['string == "%s"' % enum_value | |
| 124 for enum_value in idl_type.enum_values]) | |
| 125 IdlTypeBase.enum_validation_expression = property(enum_validation_expression) | |
| 126 | |
| 127 | |
| 128 def scoped_name(interface, definition, base_name): | |
| 129 # partial interfaces are implemented as separate classes, with their members | |
| 130 # implemented as static member functions | |
| 131 partial_interface_implemented_as = definition.extended_attributes.get('Parti
alInterfaceImplementedAs') | |
| 132 if partial_interface_implemented_as: | |
| 133 return '%s::%s' % (partial_interface_implemented_as, base_name) | |
| 134 if (definition.is_static or | |
| 135 definition.name in ('Constructor', 'NamedConstructor')): | |
| 136 return '%s::%s' % (cpp_name(interface), base_name) | |
| 137 return 'impl->%s' % base_name | |
| 138 | |
| 139 | |
| 140 ################################################################################ | |
| 141 # Specific extended attributes | |
| 142 ################################################################################ | |
| 143 | |
| 144 | |
| 145 # [CallWith] | |
| 146 CALL_WITH_ARGUMENTS = { | |
| 147 'ScriptState': 'scriptState', | |
| 148 'ExecutionContext': 'executionContext', | |
| 149 'ScriptArguments': 'scriptArguments.release()', | |
| 150 'ActiveWindow': 'callingDOMWindow(info.GetIsolate())', | |
| 151 'FirstWindow': 'enteredDOMWindow(info.GetIsolate())', | |
| 152 'Document': 'document', | |
| 153 } | |
| 154 # List because key order matters, as we want arguments in deterministic order | |
| 155 CALL_WITH_VALUES = [ | |
| 156 'ScriptState', | |
| 157 'ExecutionContext', | |
| 158 'ScriptArguments', | |
| 159 'ActiveWindow', | |
| 160 'FirstWindow', | |
| 161 'Document', | |
| 162 ] | |
| 163 | |
| 164 | |
| 165 def call_with_arguments(call_with_values): | |
| 166 if not call_with_values: | |
| 167 return [] | |
| 168 return [CALL_WITH_ARGUMENTS[value] | |
| 169 for value in CALL_WITH_VALUES | |
| 170 if extended_attribute_value_contains(call_with_values, value)] | |
| 171 | |
| 172 | |
| 173 # [Exposed] | |
| 174 EXPOSED_EXECUTION_CONTEXT_METHOD = { | |
| 175 'Window': 'isDocument', | |
| 176 } | |
| 177 | |
| 178 | |
| 179 def exposed(definition_or_member, interface): | |
| 180 exposure_set = extended_attribute_value_as_list(definition_or_member, 'Expos
ed') | |
| 181 if not exposure_set: | |
| 182 return None | |
| 183 | |
| 184 interface_exposure_set = expanded_exposure_set_for_interface(interface) | |
| 185 | |
| 186 # Methods must not be exposed to a broader scope than their interface. | |
| 187 if not set(exposure_set).issubset(interface_exposure_set): | |
| 188 raise ValueError('Interface members\' exposure sets must be a subset of
the interface\'s.') | |
| 189 | |
| 190 exposure_checks = [] | |
| 191 for environment in exposure_set: | |
| 192 # Methods must be exposed on one of the scopes known to Blink. | |
| 193 if environment not in EXPOSED_EXECUTION_CONTEXT_METHOD: | |
| 194 raise ValueError('Values for the [Exposed] annotation must reflect t
o a valid exposure scope.') | |
| 195 | |
| 196 exposure_checks.append('context->%s()' % EXPOSED_EXECUTION_CONTEXT_METHO
D[environment]) | |
| 197 | |
| 198 return ' || '.join(exposure_checks) | |
| 199 | |
| 200 | |
| 201 def expanded_exposure_set_for_interface(interface): | |
| 202 exposure_set = extended_attribute_value_as_list(interface, 'Exposed') | |
| 203 return sorted(set(exposure_set)) | |
| 204 | |
| 205 | |
| 206 # [ImplementedAs] | |
| 207 def cpp_name(definition_or_member): | |
| 208 extended_attributes = definition_or_member.extended_attributes | |
| 209 if 'ImplementedAs' not in extended_attributes: | |
| 210 return definition_or_member.name | |
| 211 return extended_attributes['ImplementedAs'] | |
| OLD | NEW |