| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from code import Code | 5 from code import Code |
| 6 from model import PropertyType | 6 from model import PropertyType |
| 7 | 7 |
| 8 from datetime import datetime | 8 from datetime import datetime |
| 9 | 9 |
| 10 LICENSE = """// Copyright %s The Chromium Authors. All rights reserved. | 10 LICENSE = """// Copyright %s The Chromium Authors. All rights reserved. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 def GetLicense(self): | 23 def GetLicense(self): |
| 24 """Returns the license text for JS extern and interface files. | 24 """Returns the license text for JS extern and interface files. |
| 25 """ | 25 """ |
| 26 return (LICENSE % datetime.now().year) | 26 return (LICENSE % datetime.now().year) |
| 27 | 27 |
| 28 def GetInfo(self, tool): | 28 def GetInfo(self, tool): |
| 29 """Returns text describing how the file was generated. | 29 """Returns text describing how the file was generated. |
| 30 """ | 30 """ |
| 31 return (INFO % tool) | 31 return (INFO % tool) |
| 32 | 32 |
| 33 def GenerateObjectDefinition(self, namespace_name, properties): | 33 def AppendObjectDefinition(self, c, namespace_name, properties, |
| 34 new_line=True): |
| 34 """Given an OrderedDict of properties, returns a Code containing the | 35 """Given an OrderedDict of properties, returns a Code containing the |
| 35 description of an object. | 36 description of an object. |
| 36 """ | 37 """ |
| 37 if not properties: return Code() | 38 if not properties: return |
| 38 | 39 |
| 39 c = Code() | 40 c.Sblock('{', new_line=new_line) |
| 40 c.Sblock('{') | |
| 41 first = True | 41 first = True |
| 42 for field, prop in properties.items(): | 42 for field, prop in properties.items(): |
| 43 # Avoid trailing comma. | 43 # Avoid trailing comma. |
| 44 # TODO(devlin): This will be unneeded, if/when | 44 # TODO(devlin): This will be unneeded, if/when |
| 45 # https://github.com/google/closure-compiler/issues/796 is fixed. | 45 # https://github.com/google/closure-compiler/issues/796 is fixed. |
| 46 if not first: | 46 if not first: |
| 47 c.Append(',', new_line=False) | 47 c.Append(',', new_line=False) |
| 48 first = False | 48 first = False |
| 49 js_type = self._TypeToJsType(namespace_name, prop.type_) | 49 js_type = self._TypeToJsType(namespace_name, prop.type_) |
| 50 if prop.optional: | 50 if prop.optional: |
| 51 js_type = (Code(). | 51 js_type = (Code().Append('(') |
| 52 Append('('). | 52 .Concat(js_type, new_line=False) |
| 53 Concat(js_type, new_line=False). | 53 .Append('|undefined)', new_line=False)) |
| 54 Append('|undefined)', new_line=False)) | |
| 55 c.Append('%s: ' % field, strip_right=False) | 54 c.Append('%s: ' % field, strip_right=False) |
| 56 c.Concat(js_type, new_line=False) | 55 c.Concat(js_type, new_line=False) |
| 57 | 56 |
| 58 c.Eblock('}') | 57 c.Eblock('}') |
| 59 | 58 |
| 60 return c | 59 def AppendFunctionJsDoc(self, c, namespace_name, function): |
| 61 | 60 """Appends the documentation for a function as a Code. |
| 62 def GenerateFunctionJsDoc(self, namespace_name, function): | |
| 63 """Generates the documentation for a function as a Code. | |
| 64 | 61 |
| 65 Returns an empty code object if the object has no documentation. | 62 Returns an empty code object if the object has no documentation. |
| 66 """ | 63 """ |
| 67 c = Code() | |
| 68 c.Sblock(line='/**', line_prefix=' * ') | 64 c.Sblock(line='/**', line_prefix=' * ') |
| 69 | 65 |
| 70 if function.description: | 66 if function.description: |
| 71 c.Comment(function.description, comment_prefix='') | 67 c.Comment(function.description, comment_prefix='') |
| 72 | 68 |
| 73 def append_field(c, tag, js_type, name, optional, description): | 69 def append_field(c, tag, js_type, name, optional, description): |
| 74 c.Append('@%s {' % tag) | 70 c.Append('@%s {' % tag) |
| 75 c.Concat(js_type, new_line=False) | 71 c.Concat(js_type, new_line=False) |
| 76 if optional: | 72 if optional: |
| 77 c.Append('=', new_line=False) | 73 c.Append('=', new_line=False) |
| 78 c.Append('} %s' % name, new_line=False) | 74 c.Append('}', new_line=False) |
| 75 c.Comment(' %s' % name, comment_prefix='', wrap_indent=4, new_line=False) |
| 79 if description: | 76 if description: |
| 80 c.Comment(' %s' % description, comment_prefix='', | 77 c.Comment(' %s' % description, comment_prefix='', |
| 81 wrap_indent=4, new_line=False) | 78 wrap_indent=4, new_line=False) |
| 82 | 79 |
| 83 for param in function.params: | 80 for param in function.params: |
| 84 append_field(c, 'param', self._TypeToJsType(namespace_name, param.type_), | 81 append_field(c, 'param', |
| 82 self._TypeToJsType(namespace_name, param.type_), |
| 85 param.name, param.optional, param.description) | 83 param.name, param.optional, param.description) |
| 86 | 84 |
| 87 if function.callback: | 85 if function.callback: |
| 88 append_field(c, 'param', | 86 append_field(c, 'param', |
| 89 self._FunctionToJsFunction(namespace_name, | 87 self._FunctionToJsFunction(namespace_name, |
| 90 function.callback), | 88 function.callback), |
| 91 function.callback.name, function.callback.optional, | 89 function.callback.name, function.callback.optional, |
| 92 function.callback.description) | 90 function.callback.description) |
| 93 | 91 |
| 94 if function.returns: | 92 if function.returns: |
| 95 append_field(c, 'return', | 93 append_field(c, 'return', |
| 96 self._TypeToJsType(namespace_name, function.returns), | 94 self._TypeToJsType(namespace_name, function.returns), |
| 97 '', False, function.returns.description) | 95 '', False, function.returns.description) |
| 98 | 96 |
| 99 if function.deprecated: | 97 if function.deprecated: |
| 100 c.Append('@deprecated %s' % function.deprecated) | 98 c.Append('@deprecated %s' % function.deprecated) |
| 101 | 99 |
| 102 c.Append(self.GenerateSeeLink(namespace_name, 'method', function.name)) | 100 c.Append(self.GetSeeLink(namespace_name, 'method', function.name)) |
| 103 | 101 |
| 104 c.Eblock(' */') | 102 c.Eblock(' */') |
| 105 return c | |
| 106 | 103 |
| 107 def _FunctionToJsFunction(self, namespace_name, function): | 104 def _FunctionToJsFunction(self, namespace_name, function): |
| 108 """Converts a model.Function to a JS type (i.e., function([params])...)""" | 105 """Converts a model.Function to a JS type (i.e., function([params])...)""" |
| 109 c = Code() | 106 c = Code() |
| 110 c.Append('function(') | 107 c.Append('function(') |
| 111 for i, param in enumerate(function.params): | 108 for i, param in enumerate(function.params): |
| 112 c.Concat(self._TypeToJsType(namespace_name, param.type_), new_line=False) | 109 c.Concat(self._TypeToJsType(namespace_name, param.type_), new_line=False) |
| 113 if i is not len(function.params) - 1: | 110 if i is not len(function.params) - 1: |
| 114 c.Append(', ', new_line=False, strip_right=False) | 111 c.Append(', ', new_line=False, strip_right=False) |
| 115 c.Append('):', new_line=False) | 112 c.Append('):', new_line=False) |
| 116 | 113 |
| 117 if function.returns: | 114 if function.returns: |
| 118 c.Concat(self._TypeToJsType(namespace_name, function.returns), | 115 c.Concat(self._TypeToJsType(namespace_name, function.returns), |
| 119 new_line=False) | 116 new_line=False) |
| 120 else: | 117 else: |
| 121 c.Append('void', new_line=False) | 118 c.Append('void', new_line=False) |
| 122 | 119 |
| 123 return c | 120 return c |
| 124 | 121 |
| 125 def _TypeToJsType(self, namespace_name, js_type): | 122 def _TypeToJsType(self, namespace_name, js_type): |
| 126 """Converts a model.Type to a JS type (number, Array, etc.)""" | 123 """Converts a model.Type to a JS type (number, Array, etc.)""" |
| 127 if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE): | 124 if js_type.property_type in (PropertyType.INTEGER, PropertyType.DOUBLE): |
| 128 return Code().Append('number') | 125 return Code().Append('number') |
| 129 if js_type.property_type is PropertyType.OBJECT: | 126 if js_type.property_type is PropertyType.OBJECT: |
| 130 if js_type.properties: | 127 if js_type.properties: |
| 131 return self.GenerateObjectDefinition(namespace_name, | 128 c = Code() |
| 132 js_type.properties) | 129 self.AppendObjectDefinition(c, namespace_name, js_type.properties) |
| 130 return c |
| 133 return Code().Append('Object') | 131 return Code().Append('Object') |
| 134 if js_type.property_type is PropertyType.ARRAY: | 132 if js_type.property_type is PropertyType.ARRAY: |
| 135 return (Code().Append('!Array<'). | 133 return (Code().Append('!Array<'). |
| 136 Concat(self._TypeToJsType(namespace_name, js_type.item_type), | 134 Concat(self._TypeToJsType(namespace_name, js_type.item_type), |
| 137 new_line=False). | 135 new_line=False). |
| 138 Append('>', new_line=False)) | 136 Append('>', new_line=False)) |
| 139 if js_type.property_type is PropertyType.REF: | 137 if js_type.property_type is PropertyType.REF: |
| 140 ref_type = '!chrome.%s.%s' % (namespace_name, js_type.ref_type) | 138 ref_type = '!chrome.%s.%s' % (namespace_name, js_type.ref_type) |
| 141 return Code().Append(ref_type) | 139 return Code().Append(ref_type) |
| 142 if js_type.property_type is PropertyType.CHOICES: | 140 if js_type.property_type is PropertyType.CHOICES: |
| 143 c = Code() | 141 c = Code() |
| 144 c.Append('(') | 142 c.Append('(') |
| 145 for i, choice in enumerate(js_type.choices): | 143 for i, choice in enumerate(js_type.choices): |
| 146 c.Concat(self._TypeToJsType(namespace_name, choice), new_line=False) | 144 c.Concat(self._TypeToJsType(namespace_name, choice), new_line=False) |
| 147 if i is not len(js_type.choices) - 1: | 145 if i is not len(js_type.choices) - 1: |
| 148 c.Append('|', new_line=False) | 146 c.Append('|', new_line=False) |
| 149 c.Append(')', new_line=False) | 147 c.Append(')', new_line=False) |
| 150 return c | 148 return c |
| 151 if js_type.property_type is PropertyType.FUNCTION: | 149 if js_type.property_type is PropertyType.FUNCTION: |
| 152 return self._FunctionToJsFunction(namespace_name, js_type.function) | 150 return self._FunctionToJsFunction(namespace_name, js_type.function) |
| 153 if js_type.property_type is PropertyType.ANY: | 151 if js_type.property_type is PropertyType.ANY: |
| 154 return Code().Append('*') | 152 return Code().Append('*') |
| 155 if js_type.property_type.is_fundamental: | 153 if js_type.property_type.is_fundamental: |
| 156 return Code().Append(js_type.property_type.name) | 154 return Code().Append(js_type.property_type.name) |
| 157 return Code().Append('?') # TODO(tbreisacher): Make this more specific. | 155 return Code().Append('?') # TODO(tbreisacher): Make this more specific. |
| 158 | 156 |
| 159 def GenerateSeeLink(self, namespace_name, object_type, object_name): | 157 def GetSeeLink(self, namespace_name, object_type, object_name): |
| 160 """Generates a @see link for a given API 'object' (type, method, or event). | 158 """Returns a @see link for a given API 'object' (type, method, or event). |
| 161 """ | 159 """ |
| 162 | 160 |
| 163 # NOTE(devlin): This is kind of a hack. Some APIs will be hosted on | 161 # NOTE(devlin): This is kind of a hack. Some APIs will be hosted on |
| 164 # developer.chrome.com/apps/ instead of /extensions/, and some APIs have | 162 # developer.chrome.com/apps/ instead of /extensions/, and some APIs have |
| 165 # '.'s in them (like app.window), which should resolve to 'app_window'. | 163 # '.'s in them (like app.window), which should resolve to 'app_window'. |
| 166 # Luckily, the doc server has excellent url resolution, and knows exactly | 164 # Luckily, the doc server has excellent url resolution, and knows exactly |
| 167 # what we mean. This saves us from needing any complicated logic here. | 165 # what we mean. This saves us from needing any complicated logic here. |
| 168 return ('@see https://developer.chrome.com/extensions/%s#%s-%s' % | 166 return ('@see https://developer.chrome.com/extensions/%s#%s-%s' % |
| 169 (namespace_name, object_type, object_name)) | 167 (namespace_name, object_type, object_name)) |
| OLD | NEW |