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

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

Issue 291903003: Generate java bindings for constants. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Follow review Created 6 years, 7 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
(Empty)
1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Generates java source files from a mojom.Module."""
6
7 import argparse
8 import os
9 import re
10
11 import mojom.generate.generator as generator
12 import mojom.generate.module as mojom
13 from mojom.generate.template_expander import UseJinja
14
15
16 GENERATOR_PREFIX = 'java'
17
18 _spec_to_java_type = {
19 'b': 'boolean',
20 'd': 'double',
21 'f': 'float',
22 'h:d:c': 'org.chromium.mojo.system.DataPipe.ConsumerHandle',
23 'h:d:p': 'org.chromium.mojo.system.DataPipe.ProducerHandle',
24 'h:m': 'org.chromium.mojo.system.MessagePipeHandle',
25 'h': 'org.chromium.mojo.system.UntypedHandle',
26 'h:s': 'org.chromium.mojo.system.SharedBufferHandle',
27 'i16': 'short',
28 'i32': 'int',
29 'i64': 'long',
30 'i8': 'byte',
31 's': 'String',
32 'u16': 'short',
33 'u32': 'int',
34 'u64': 'long',
35 'u8': 'byte',
36 }
37
38
39 def NameToComponent(name):
40 def _IsCut(i):
41 if i == 0 or i == len(name):
42 return True
43 if name[i].islower():
44 return False
45 if name[i-1].isupper() and (i == len(name) -1 or name[i+1].isupper()):
46 return False
47 return True
rmcilroy 2014/05/26 11:13:48 How about using the regex's I suggested in the las
qsr 2014/05/26 12:05:42 Done, but I do not find that clearer. Also didn't
48 if '_' in name:
49 return [item for sublist in [NameToComponent(y) for y in name.split('_')]
50 for item in sublist]
51 pos = [i for i in xrange(len(name) + 1) if _IsCut(i)]
52 return [name[pos[j]:pos[j+1]].lower() for j in xrange(len(pos)-1)]
53
54 def CapitalizeFirst(string):
55 return string[0].upper() + string[1:]
56
57 def UpperCamelCase(name):
58 return ''.join([CapitalizeFirst(x) for x in NameToComponent(name)])
59
60 def CamelCase(name):
61 uccc = UpperCamelCase(name)
62 return uccc[0].lower() + uccc[1:]
63
64 def UpperCaseHackerStyle(name):
rmcilroy 2014/05/26 11:13:48 I've never heard of hacker style and can't find it
qsr 2014/05/26 12:05:42 Done. Don't remember where I found it was called h
65 components = NameToComponent(name)
66 if components[0] == 'k':
67 components = components[1:]
68 return '_'.join([x.upper() for x in components])
69
70 def GetNameForElement(element):
71 if (isinstance(element, mojom.Enum) or
72 isinstance(element, mojom.Interface) or
73 isinstance(element, mojom.Struct)):
74 return UpperCamelCase(element.name)
75 if (isinstance(element, mojom.Method) or
76 isinstance(element, mojom.Parameter) or
77 isinstance(element, mojom.Field)):
78 return CamelCase(element.name)
79 if isinstance(element, mojom.EnumValue):
80 return (UpperCamelCase(element.enum_name) + '.' +
81 UpperCaseHackerStyle(element.name))
82 if (isinstance(element, mojom.NamedValue) or
83 isinstance(element, mojom.Constant)):
84 return UpperCaseHackerStyle(element.name)
85 raise Exception("Unexpected element: " % element)
86
87 def GetPackage(module):
88 if 'JavaPackage' not in module.attributes:
rmcilroy 2014/05/26 11:13:48 In the case of this function, I still think if/els
qsr 2014/05/26 12:05:42 Move the conditional back. But I really don't like
rmcilroy 2014/05/27 09:44:34 OK, we disagree on this, but I'm not going to bike
89 return "org.chromium.mojom." + module.namespace
90 package = module.attributes['JavaPackage']
91 if isinstance(package, basestring):
92 return package
93 assert package[0] == 'EXPRESSION'
94 assert len(package[1]) == 1
95 return package[1][0][1:-1].encode('string_escape')
96
97 def GetNameForKind(kind):
98 def _GetNameHierachy(kind):
99 hierachy = []
100 if kind.parent_kind:
101 hierachy = _GetNameHierachy(kind.parent_kind)
102 hierachy.append(kind.name)
103 return hierachy
104
105 elements = [GetPackage(kind.module)]
106 elements += _GetNameHierachy(kind)
107 return '.'.join(elements)
108
109 def GetJavaType(kind):
110 if isinstance(kind, (mojom.Struct, mojom.Interface)):
111 return GetNameForKind(kind)
112 if isinstance(kind, mojom.Array):
113 return "%s[]" % GetJavaType(kind.kind)
114 if isinstance(kind, mojom.Enum):
115 return "int"
116 return _spec_to_java_type[kind.spec]
117
118 def TranslateConstants(token, module):
119 def _TranslateNamedValue(named_value):
120 entity_value = GetNameForElement(named_value)
rmcilroy 2014/05/26 11:13:48 /s/entity_value/entity_name I think.
qsr 2014/05/26 12:05:42 Done.
121 # Handle the case where named_value is a module level constant:
122 if (not isinstance(named_value, mojom.EnumValue) and
rmcilroy 2014/05/26 11:13:48 This seems a bit confusing to me, how about: if n
qsr 2014/05/26 12:05:42 I still think the else after a return is not in an
rmcilroy 2014/05/27 09:44:34 Ok, this looks better, thanks.
123 not named_value.parent_kind):
124 return (GetConstantsMainEntityFullyQualifiedName(named_value.module) +
125 '.'+ entity_value)
126 if named_value.parent_kind:
127 return GetJavaType(named_value.parent_kind) + '.' + entity_value
128 return GetPackage(named_value.module) + '.' + entity_value
129
130 if isinstance(token, mojom.NamedValue):
131 return _TranslateNamedValue(token)
132 if re.match('^[0-9]+$', token):
rmcilroy 2014/05/26 11:13:48 Comment that you add Long suffix to all number lit
qsr 2014/05/26 12:05:42 Done.
133 return token + 'L'
134 return token
135
136 def ExpressionToText(value, module):
137 if value[0] != "EXPRESSION":
138 raise Exception("Expected EXPRESSION, got" + value)
139 return "".join(generator.ExpressionMapper(value,
140 lambda token: TranslateConstants(token, module)))
141
142 def GetConstantsMainEntityFullyQualifiedName(module):
143 package = GetPackage(module)
144 return GetPackage(module) + '.' + GetConstantsMainEntityName(module)
145
146 def GetConstantsMainEntityName(module):
147 # This constructs the name of the embedding classes for module level constants
148 # by extracting the mojom's filename and prepending it to Constants.
149 return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) +
150 'Constants')
151
152 class Generator(generator.Generator):
153
154 java_filters = {
155 "expression_to_text": ExpressionToText,
156 "java_type": GetJavaType,
157 "name": GetNameForElement,
158 "verify_token_type": generator.VerifyTokenType,
159 }
160
161 def GetJinjaExports(self):
162 return {
163 "module": self.module,
164 "package": GetPackage(self.module),
165 }
166
167 @UseJinja("java_templates/constants.java.tmpl", filters=java_filters,
168 lstrip_blocks=True, trim_blocks=True)
169 def GenerateConstantsSource(self, module):
170 exports = self.GetJinjaExports()
171 exports.update({"main_entity": GetConstantsMainEntityName(module),
172 "constants": module.constants})
173 return exports
174
175 def GenerateFiles(self, unparsed_args):
176 parser = argparse.ArgumentParser()
177 parser.add_argument("--java_output_directory", dest="java_output_directory")
178 args = parser.parse_args(unparsed_args)
179 if self.output_dir and args.java_output_directory:
180 self.output_dir = os.path.join(args.java_output_directory,
181 GetPackage(self.module).replace('.', '/'))
182 if not os.path.exists(self.output_dir):
183 os.makedirs(self.output_dir)
184
185 if self.module.constants:
186 self.Write(self.GenerateConstantsSource(self.module),
187 "%s.java" % GetConstantsMainEntityName(self.module))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698