Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Side by Side Diff: mojo/public/tools/bindings/generators/mojom_java_generator.py

Issue 306893010: Generate java bindings for structs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Re-upload after revert Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 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 """Generates java source files from a mojom.Module.""" 5 """Generates java source files from a mojom.Module."""
6 6
7 import argparse 7 import argparse
8 import os 8 import os
9 import re 9 import re
10 10
11 from jinja2 import contextfilter
12
11 import mojom.generate.generator as generator 13 import mojom.generate.generator as generator
12 import mojom.generate.module as mojom 14 import mojom.generate.module as mojom
13 from mojom.generate.template_expander import UseJinja 15 from mojom.generate.template_expander import UseJinja
14 16
15 17
16 GENERATOR_PREFIX = 'java' 18 GENERATOR_PREFIX = 'java'
17 19
18 _spec_to_java_type = { 20 _spec_to_java_type = {
19 'b': 'boolean', 21 'b': 'boolean',
20 'd': 'double', 22 'd': 'double',
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 uccc = UpperCamelCase(name) 57 uccc = UpperCamelCase(name)
56 return uccc[0].lower() + uccc[1:] 58 return uccc[0].lower() + uccc[1:]
57 59
58 def ConstantStyle(name): 60 def ConstantStyle(name):
59 components = NameToComponent(name) 61 components = NameToComponent(name)
60 if components[0] == 'k': 62 if components[0] == 'k':
61 components = components[1:] 63 components = components[1:]
62 return '_'.join([x.upper() for x in components]) 64 return '_'.join([x.upper() for x in components])
63 65
64 def GetNameForElement(element): 66 def GetNameForElement(element):
65 if (isinstance(element, mojom.Enum) or 67 if isinstance(element, (mojom.Enum,
66 isinstance(element, mojom.Interface) or 68 mojom.Interface,
67 isinstance(element, mojom.Struct)): 69 mojom.Struct)):
68 return UpperCamelCase(element.name) 70 return UpperCamelCase(element.name)
69 if (isinstance(element, mojom.Method) or 71 if isinstance(element, mojom.InterfaceRequest):
70 isinstance(element, mojom.Parameter) or 72 return GetNameForElement(element.kind)
71 isinstance(element, mojom.Field)): 73 if isinstance(element, (mojom.Method,
74 mojom.Parameter,
75 mojom.Field)):
72 return CamelCase(element.name) 76 return CamelCase(element.name)
73 if isinstance(element, mojom.EnumValue): 77 if isinstance(element, mojom.EnumValue):
74 return (UpperCamelCase(element.enum_name) + '.' + 78 return (UpperCamelCase(element.enum_name) + '.' +
75 ConstantStyle(element.name)) 79 ConstantStyle(element.name))
76 if (isinstance(element, mojom.NamedValue) or 80 if isinstance(element, (mojom.NamedValue,
77 isinstance(element, mojom.Constant)): 81 mojom.Constant)):
78 return ConstantStyle(element.name) 82 return ConstantStyle(element.name)
79 raise Exception("Unexpected element: " % element) 83 raise Exception("Unexpected element: " % element)
80 84
81 def ParseStringAttribute(attribute): 85 def ParseStringAttribute(attribute):
82 assert isinstance(attribute, basestring) 86 assert isinstance(attribute, basestring)
83 return attribute 87 return attribute
84 88
85 def GetPackage(module): 89 def GetPackage(module):
86 if 'JavaPackage' in module.attributes: 90 if 'JavaPackage' in module.attributes:
87 return ParseStringAttribute(module.attributes['JavaPackage']) 91 return ParseStringAttribute(module.attributes['JavaPackage'])
88 # Default package. 92 # Default package.
89 return "org.chromium.mojom." + module.namespace 93 return "org.chromium.mojom." + module.namespace
90 94
91 def GetNameForKind(kind): 95 def GetNameForKind(context, kind):
92 def _GetNameHierachy(kind): 96 def _GetNameHierachy(kind):
93 hierachy = [] 97 hierachy = []
94 if kind.parent_kind: 98 if kind.parent_kind:
95 hierachy = _GetNameHierachy(kind.parent_kind) 99 hierachy = _GetNameHierachy(kind.parent_kind)
96 hierachy.append(kind.name) 100 hierachy.append(GetNameForElement(kind))
97 return hierachy 101 return hierachy
98 102
99 elements = [GetPackage(kind.module)] 103 module = context.resolve('module')
104 elements = []
105 if GetPackage(module) != GetPackage(kind.module):
106 elements += [GetPackage(kind.module)]
100 elements += _GetNameHierachy(kind) 107 elements += _GetNameHierachy(kind)
101 return '.'.join(elements) 108 return '.'.join(elements)
102 109
103 def GetJavaType(kind): 110 @contextfilter
111 def GetJavaType(context, kind):
104 if isinstance(kind, (mojom.Struct, mojom.Interface)): 112 if isinstance(kind, (mojom.Struct, mojom.Interface)):
105 return GetNameForKind(kind) 113 return GetNameForKind(context, kind)
106 if isinstance(kind, mojom.Array): 114 if isinstance(kind, mojom.InterfaceRequest):
107 return "%s[]" % GetJavaType(kind.kind) 115 return GetNameForKind(context, kind.kind)
116 if isinstance(kind, (mojom.Array, mojom.FixedArray)):
117 return "%s[]" % GetJavaType(context, kind.kind)
108 if isinstance(kind, mojom.Enum): 118 if isinstance(kind, mojom.Enum):
109 return "int" 119 return "int"
110 return _spec_to_java_type[kind.spec] 120 return _spec_to_java_type[kind.spec]
111 121
112 def ExpressionToText(token): 122 def IsHandle(kind):
123 return kind.spec[0] == 'h'
124
125 @contextfilter
126 def DefaultValue(context, field):
127 assert field.default
128 if isinstance(field.kind, mojom.Struct):
129 assert field.default == "default"
130 return "new %s()" % GetJavaType(context, field.kind)
131 return "(%s) %s" % (GetJavaType(context, field.kind),
132 ExpressionToText(context, field.default))
133
134 @contextfilter
135 def ExpressionToText(context, token):
113 def _TranslateNamedValue(named_value): 136 def _TranslateNamedValue(named_value):
114 entity_name = GetNameForElement(named_value) 137 entity_name = GetNameForElement(named_value)
115 if named_value.parent_kind: 138 if named_value.parent_kind:
116 return GetJavaType(named_value.parent_kind) + '.' + entity_name 139 return GetJavaType(context, named_value.parent_kind) + '.' + entity_name
117 # Handle the case where named_value is a module level constant: 140 # Handle the case where named_value is a module level constant:
118 if not isinstance(named_value, mojom.EnumValue): 141 if not isinstance(named_value, mojom.EnumValue):
119 entity_name = (GetConstantsMainEntityName(named_value.module) + '.' + 142 entity_name = (GetConstantsMainEntityName(named_value.module) + '.' +
120 entity_name) 143 entity_name)
144 if GetPackage(named_value.module) == GetPackage(context.resolve('module')):
145 return entity_name
121 return GetPackage(named_value.module) + '.' + entity_name 146 return GetPackage(named_value.module) + '.' + entity_name
122 147
123 if isinstance(token, mojom.NamedValue): 148 if isinstance(token, mojom.NamedValue):
124 return _TranslateNamedValue(token) 149 return _TranslateNamedValue(token)
125 # Add Long suffix to all number literals. 150 # Add Long suffix to all number literals.
126 if re.match('^[0-9]+$', token): 151 if re.match('^[0-9]+$', token):
127 return token + 'L' 152 return token + 'L'
128 return token 153 return token
129 154
130 def GetConstantsMainEntityName(module): 155 def GetConstantsMainEntityName(module):
131 if 'JavaConstantsClassName' in module.attributes: 156 if 'JavaConstantsClassName' in module.attributes:
132 return ParseStringAttribute(module.attributes['JavaConstantsClassName']) 157 return ParseStringAttribute(module.attributes['JavaConstantsClassName'])
133 # This constructs the name of the embedding classes for module level constants 158 # This constructs the name of the embedding classes for module level constants
134 # by extracting the mojom's filename and prepending it to Constants. 159 # by extracting the mojom's filename and prepending it to Constants.
135 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) + 160 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) +
136 'Constants') 161 'Constants')
137 162
138 class Generator(generator.Generator): 163 class Generator(generator.Generator):
139 164
140 java_filters = { 165 java_filters = {
166 "default_value": DefaultValue,
141 "expression_to_text": ExpressionToText, 167 "expression_to_text": ExpressionToText,
168 "is_handle": IsHandle,
142 "java_type": GetJavaType, 169 "java_type": GetJavaType,
143 "name": GetNameForElement, 170 "name": GetNameForElement,
144 } 171 }
145 172
146 def GetJinjaExports(self): 173 def GetJinjaExports(self):
147 return { 174 return {
148 "module": self.module, 175 "module": self.module,
149 "package": GetPackage(self.module), 176 "package": GetPackage(self.module),
150 } 177 }
151 178
152 @UseJinja("java_templates/enum.java.tmpl", filters=java_filters, 179 @UseJinja("java_templates/enum.java.tmpl", filters=java_filters)
153 lstrip_blocks=True, trim_blocks=True)
154 def GenerateEnumSource(self, enum): 180 def GenerateEnumSource(self, enum):
155 exports = self.GetJinjaExports() 181 exports = self.GetJinjaExports()
156 exports.update({"enum": enum}) 182 exports.update({"enum": enum})
157 return exports 183 return exports
158 184
159 @UseJinja("java_templates/constants.java.tmpl", filters=java_filters, 185 @UseJinja("java_templates/struct.java.tmpl", filters=java_filters)
160 lstrip_blocks=True, trim_blocks=True) 186 def GenerateStructSource(self, struct):
187 exports = self.GetJinjaExports()
188 exports.update({"struct": struct})
189 return exports
190
191 @UseJinja("java_templates/constants.java.tmpl", filters=java_filters)
161 def GenerateConstantsSource(self, module): 192 def GenerateConstantsSource(self, module):
162 exports = self.GetJinjaExports() 193 exports = self.GetJinjaExports()
163 exports.update({"main_entity": GetConstantsMainEntityName(module), 194 exports.update({"main_entity": GetConstantsMainEntityName(module),
164 "constants": module.constants}) 195 "constants": module.constants})
165 return exports 196 return exports
166 197
167 def GenerateFiles(self, unparsed_args): 198 def GenerateFiles(self, unparsed_args):
168 parser = argparse.ArgumentParser() 199 parser = argparse.ArgumentParser()
169 parser.add_argument("--java_output_directory", dest="java_output_directory") 200 parser.add_argument("--java_output_directory", dest="java_output_directory")
170 args = parser.parse_args(unparsed_args) 201 args = parser.parse_args(unparsed_args)
171 if self.output_dir and args.java_output_directory: 202 if self.output_dir and args.java_output_directory:
172 self.output_dir = os.path.join(args.java_output_directory, 203 self.output_dir = os.path.join(args.java_output_directory,
173 GetPackage(self.module).replace('.', '/')) 204 GetPackage(self.module).replace('.', '/'))
174 if not os.path.exists(self.output_dir): 205 if not os.path.exists(self.output_dir):
175 try: 206 try:
176 os.makedirs(self.output_dir) 207 os.makedirs(self.output_dir)
177 except: 208 except:
178 # Ignore errors on directory creation. 209 # Ignore errors on directory creation.
179 pass 210 pass
180 211
181 for enum in self.module.enums: 212 for enum in self.module.enums:
182 self.Write(self.GenerateEnumSource(enum), 213 self.Write(self.GenerateEnumSource(enum),
183 "%s.java" % GetNameForElement(enum)) 214 "%s.java" % GetNameForElement(enum))
184 215
216 for struct in self.module.structs:
217 self.Write(self.GenerateStructSource(struct),
218 "%s.java" % GetNameForElement(struct))
219
185 if self.module.constants: 220 if self.module.constants:
186 self.Write(self.GenerateConstantsSource(self.module), 221 self.Write(self.GenerateConstantsSource(self.module),
187 "%s.java" % GetConstantsMainEntityName(self.module)) 222 "%s.java" % GetConstantsMainEntityName(self.module))
223
224 def GetJinjaParameters(self):
225 return {
226 'lstrip_blocks': True,
227 'trim_blocks': True,
228 }
229
230 def GetGlobals(self):
231 return {
232 'module': self.module,
233 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698