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

Side by Side Diff: base/android/jni_generator/jni_generator.py

Issue 11339013: Android: passes a list of qualified JNI parameters as a param to the generator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Yaron's and Nico's comments Created 8 years, 1 month 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 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # TODO (qinmin): Need to refactor this file as base should not know about
7 # higher level concepts. Currently this file has knowledge about higher level
8 # java classes.
9
10 """Extracts native methods from a Java file and generates the JNI bindings. 6 """Extracts native methods from a Java file and generates the JNI bindings.
11 If you change this, please run and update the tests.""" 7 If you change this, please run and update the tests."""
12 8
13 import collections 9 import collections
14 import optparse 10 import optparse
15 import os 11 import os
16 import re 12 import re
17 import string 13 import string
18 from string import Template 14 from string import Template
19 import subprocess 15 import subprocess
20 import sys 16 import sys
21 import textwrap 17 import textwrap
22 import zipfile 18 import zipfile
23 19
24 UNKNOWN_JAVA_TYPE_PREFIX = 'UNKNOWN_JAVA_TYPE: '
25
26 20
27 class ParseError(Exception): 21 class ParseError(Exception):
28 """Exception thrown when we can't parse the input file.""" 22 """Exception thrown when we can't parse the input file."""
29 23
30 def __init__(self, description, *context_lines): 24 def __init__(self, description, *context_lines):
31 Exception.__init__(self) 25 Exception.__init__(self)
32 self.description = description 26 self.description = description
33 self.context_lines = context_lines 27 self.context_lines = context_lines
34 28
35 def __str__(self): 29 def __str__(self):
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 elif java_type in java_type_map: 100 elif java_type in java_type_map:
107 return java_type_map[java_type] 101 return java_type_map[java_type]
108 elif java_type.endswith('[]'): 102 elif java_type.endswith('[]'):
109 if java_type[:-2] in java_pod_type_map: 103 if java_type[:-2] in java_pod_type_map:
110 return java_pod_type_map[java_type[:-2]] + 'Array' 104 return java_pod_type_map[java_type[:-2]] + 'Array'
111 return 'jobjectArray' 105 return 'jobjectArray'
112 else: 106 else:
113 return 'jobject' 107 return 'jobject'
114 108
115 109
116 def JavaParamToJni(param): 110 class JniParams(object):
117 """Converts a java param into a JNI signature type.""" 111 _UNKNOWN_JAVA_TYPE_PREFIX = 'UNKNOWN_JAVA_TYPE: '
118 pod_param_map = { 112 _external_param_files = set()
119 'int': 'I', 113 _external_param_list = []
Nico 2012/10/31 17:41:28 Meh, that's still global state. Why not make this
bulach 2012/10/31 17:53:10 I agree, but that's a much more complex change :)
120 'boolean': 'Z',
121 'long': 'J',
122 'double': 'D',
123 'float': 'F',
124 'byte': 'B',
125 'void': 'V',
126 }
127 object_param_list = [
128 'Ljava/lang/Boolean',
129 'Ljava/lang/Integer',
130 'Ljava/lang/Long',
131 'Ljava/lang/Object',
132 'Ljava/lang/String',
133 'Ljava/util/ArrayList',
134 'Ljava/util/HashMap',
135 'Ljava/util/List',
136 'Landroid/content/Context',
137 'Landroid/graphics/Bitmap',
138 'Landroid/graphics/Canvas',
139 'Landroid/graphics/Rect',
140 'Landroid/graphics/RectF',
141 'Landroid/graphics/Matrix',
142 'Landroid/graphics/Point',
143 'Landroid/graphics/SurfaceTexture$OnFrameAvailableListener',
144 'Landroid/media/MediaPlayer',
145 'Landroid/os/Message',
146 'Landroid/view/KeyEvent',
147 'Landroid/view/Surface',
148 'Landroid/view/View',
149 'Landroid/webkit/ValueCallback',
150 'Ljava/io/InputStream',
151 'Ljava/nio/ByteBuffer',
152 'Ljava/util/Vector',
153 ]
154 app_param_list = [
155 'Landroid/graphics/SurfaceTexture',
156 'Lcom/google/android/apps/chrome/ChromeContextMenuInfo',
157 'Lcom/google/android/apps/chrome/ChromeWindow',
158 'Lcom/google/android/apps/chrome/GoogleLocationSettingsHelperImpl',
159 'Lcom/google/android/apps/chrome/OmniboxSuggestion',
160 'Lcom/google/android/apps/chrome/PageInfoViewer',
161 'Lcom/google/android/apps/chrome/Tab',
162 'Lcom/google/android/apps/chrome/infobar/AutoLogin',
163 'Lcom/google/android/apps/chrome/infobar/InfoBarContainer',
164 'Lcom/google/android/apps/chrome/infobar/InfoBarContainer$NativeInfoBar',
165 ('Lcom/google/android/apps/chrome/preferences/ChromeNativePreferences$'
166 'PasswordListObserver'),
167 'Lorg/chromium/android_webview/AwContents',
168 'Lorg/chromium/android_webview/AwContentsClient',
169 'Lorg/chromium/android_webview/AwHttpAuthHandler',
170 'Lorg/chromium/android_webview/AwContentsIoThreadClient',
171 'Lorg/chromium/android_webview/AwWebContentsDelegate',
172 'Lorg/chromium/android_webview/InterceptedRequestData',
173 'Lorg/chromium/android_webview/JsPromptResultReceiver',
174 'Lorg/chromium/android_webview/JsResultHandler',
175 'Lorg/chromium/android_webview/JsResultReceiver',
176 'Lorg/chromium/base/SystemMessageHandler',
177 'Lorg/chromium/chrome/browser/autofill/AutofillExternalDelegate',
178 'Lorg/chromium/chrome/browser/autofill/AutofillSuggestion',
179 'Lorg/chromium/chrome/browser/ChromeBrowserProvider$BookmarkNode',
180 'Lorg/chromium/chrome/browser/ChromeHttpAuthHandler',
181 'Lorg/chromium/chrome/browser/ChromeWebContentsDelegateAndroid',
182 'Lorg/chromium/chrome/browser/FindMatchRectsDetails',
183 'Lorg/chromium/chrome/browser/FindNotificationDetails',
184 'Lorg/chromium/chrome/browser/GoogleLocationSettingsHelper',
185 'Lorg/chromium/chrome/browser/GoogleLocationSettingsHelperStub',
186 'Lorg/chromium/chrome/browser/JavascriptAppModalDialog',
187 'Lorg/chromium/chrome/browser/ProcessUtils',
188 ('Lorg/chromium/chrome/browser/component/navigation_interception/'
189 'InterceptNavigationDelegate'),
190 ('Lorg/chromium/chrome/browser/component/web_contents_delegate_android/'
191 'WebContentsDelegateAndroid'),
192 'Lorg/chromium/chrome/browser/database/SQLiteCursor',
193 'Lorg/chromium/content/app/SandboxedProcessService',
194 'Lorg/chromium/content/browser/ContainerViewDelegate',
195 'Lorg/chromium/content/browser/ContentVideoView',
196 'Lorg/chromium/content/browser/ContentViewCore',
197 'Lorg/chromium/content/browser/DeviceOrientation',
198 'Lorg/chromium/content/browser/JavaInputStream',
199 'Lorg/chromium/content/browser/LocationProvider',
200 'Lorg/chromium/content/browser/SandboxedProcessArgs',
201 'Lorg/chromium/content/browser/SandboxedProcessConnection',
202 'Lorg/chromium/content/browser/TouchPoint',
203 'Lorg/chromium/content/browser/WaitableNativeEvent',
204 'Lorg/chromium/content/browser/WebContentsObserverAndroid',
205 'Lorg/chromium/content/common/DeviceInfo',
206 'Lorg/chromium/content/common/SurfaceTextureListener',
207 'Lorg/chromium/media/MediaPlayerListener',
208 'Lorg/chromium/net/NetworkChangeNotifier',
209 'Lorg/chromium/net/ProxyChangeListener',
210 'Lorg/chromium/ui/gfx/NativeWindow',
211 'Lorg/chromium/ui/SelectFileDialog',
212 ]
213 if param == 'byte[][]':
214 return '[[B'
215 prefix = ''
216 # Array?
217 if param[-2:] == '[]':
218 prefix = '['
219 param = param[:-2]
220 # Generic?
221 if '<' in param:
222 param = param[:param.index('<')]
223 if param in pod_param_map:
224 return prefix + pod_param_map[param]
225 if '/' in param:
226 # Coming from javap, use the fully qualified param directly.
227 return 'L' + param + ';'
228 for qualified_name in object_param_list + app_param_list:
229 if (qualified_name.endswith('/' + param) or
230 qualified_name.endswith('$' + param.replace('.', '$')) or
231 qualified_name == 'L' + param):
232 return prefix + qualified_name + ';'
233 else:
234 return UNKNOWN_JAVA_TYPE_PREFIX + prefix + param + ';'
235 114
115 @staticmethod
116 def ReadExternalParamList(external_param_files):
117 if not external_param_files:
118 return
119 assert not JniParams._external_param_files
120 JniParams._external_param_files = set(external_param_files)
121 for external_param_file in JniParams._external_param_files:
122 with file(external_param_file, 'r') as f:
123 contents = f.read()
124 JniParams._external_param_list += [x.strip()
125 for x in contents.splitlines()
126 if x and not x.startswith('#')]
236 127
237 def JniSignature(params, returns, wrap): 128 @staticmethod
238 """Returns the JNI signature for the given datatypes.""" 129 def JavaToJni(param):
239 items = ['('] 130 """Converts a java param into a JNI signature type."""
240 items += [JavaParamToJni(param.datatype) for param in params] 131 pod_param_map = {
241 items += [')'] 132 'int': 'I',
242 items += [JavaParamToJni(returns)] 133 'boolean': 'Z',
243 if wrap: 134 'long': 'J',
244 return '\n' + '\n'.join(['"' + item + '"' for item in items]) 135 'double': 'D',
245 else: 136 'float': 'F',
246 return '"' + ''.join(items) + '"' 137 'byte': 'B',
138 'void': 'V',
139 }
140 object_param_list = [
141 'Ljava/lang/Boolean',
142 'Ljava/lang/Integer',
143 'Ljava/lang/Long',
144 'Ljava/lang/Object',
145 'Ljava/lang/String',
146 'Ljava/util/ArrayList',
147 'Ljava/util/HashMap',
148 'Ljava/util/List',
149 'Landroid/content/Context',
150 'Landroid/graphics/Bitmap',
151 'Landroid/graphics/Canvas',
152 'Landroid/graphics/Rect',
153 'Landroid/graphics/RectF',
154 'Landroid/graphics/Matrix',
155 'Landroid/graphics/Point',
156 'Landroid/graphics/SurfaceTexture',
157 'Landroid/graphics/SurfaceTexture$OnFrameAvailableListener',
158 'Landroid/media/MediaPlayer',
159 'Landroid/os/Message',
160 'Landroid/view/KeyEvent',
161 'Landroid/view/Surface',
162 'Landroid/view/View',
163 'Landroid/webkit/ValueCallback',
164 'Ljava/io/InputStream',
165 'Ljava/nio/ByteBuffer',
166 'Ljava/util/Vector',
167 ]
168 if param == 'byte[][]':
169 return '[[B'
170 prefix = ''
171 # Array?
172 if param[-2:] == '[]':
173 prefix = '['
174 param = param[:-2]
175 # Generic?
176 if '<' in param:
177 param = param[:param.index('<')]
178 if param in pod_param_map:
179 return prefix + pod_param_map[param]
180 if '/' in param:
181 # Coming from javap, use the fully qualified param directly.
182 return 'L' + param + ';'
183 for qualified_name in object_param_list + JniParams._external_param_list:
184 if (qualified_name.endswith('/' + param) or
185 qualified_name.endswith('$' + param.replace('.', '$')) or
186 qualified_name == 'L' + param):
187 return prefix + qualified_name + ';'
188 else:
189 return JniParams._UNKNOWN_JAVA_TYPE_PREFIX + prefix + param + ';'
247 190
191 @staticmethod
192 def Signature(params, returns, wrap):
193 """Returns the JNI signature for the given datatypes."""
194 items = ['(']
195 items += [JniParams.JavaToJni(param.datatype) for param in params]
196 items += [')']
197 items += [JniParams.JavaToJni(returns)]
198 if wrap:
199 return '\n' + '\n'.join(['"' + item + '"' for item in items])
200 else:
201 return '"' + ''.join(items) + '"'
248 202
249 def ParseParams(params): 203 @staticmethod
250 """Parses the params into a list of Param objects.""" 204 def Parse(params):
251 if not params: 205 """Parses the params into a list of Param objects."""
252 return [] 206 if not params:
253 ret = [] 207 return []
254 for p in [p.strip() for p in params.split(',')]: 208 ret = []
255 items = p.split(' ') 209 for p in [p.strip() for p in params.split(',')]:
256 if 'final' in items: 210 items = p.split(' ')
257 items.remove('final') 211 if 'final' in items:
258 param = Param( 212 items.remove('final')
259 datatype=items[0], 213 param = Param(
260 name=(items[1] if len(items) > 1 else 'p%s' % len(ret)), 214 datatype=items[0],
261 ) 215 name=(items[1] if len(items) > 1 else 'p%s' % len(ret)),
262 ret += [param] 216 )
263 return ret 217 ret += [param]
218 return ret
264 219
220 @staticmethod
221 def CheckUnknownDatatypes(fully_qualified_class, items):
222 unknown_datatypes = JniParams._GetUnknownDatatypes(items)
223 if unknown_datatypes:
224 msg = ('There are a few unknown datatypes in %s' %
225 fully_qualified_class)
226 msg += '\nPlease, edit %s' % str(JniParams._external_param_files)
227 msg += '\nand add the JNI type(s):\n'
228 for unknown_datatype in unknown_datatypes:
229 msg += '\n%s in methods:\n' % unknown_datatype
230 msg += '\n '.join(unknown_datatypes[unknown_datatype])
231 raise SyntaxError(msg)
265 232
266 def GetUnknownDatatypes(items): 233 @staticmethod
267 """Returns a list containing the unknown datatypes.""" 234 def _GetUnknownDatatypes(items):
268 unknown_types = {} 235 """Returns a list containing the unknown datatypes."""
269 for item in items: 236 unknown_types = {}
270 all_datatypes = ([JavaParamToJni(param.datatype) 237 for item in items:
271 for param in item.params] + 238 all_datatypes = ([JniParams.JavaToJni(param.datatype)
272 [JavaParamToJni(item.return_type)]) 239 for param in item.params] +
273 for d in all_datatypes: 240 [JniParams.JavaToJni(item.return_type)])
274 if d.startswith(UNKNOWN_JAVA_TYPE_PREFIX): 241 for d in all_datatypes:
275 unknown_types[d] = (unknown_types.get(d, []) + 242 if d.startswith(JniParams._UNKNOWN_JAVA_TYPE_PREFIX):
276 [item.name or 'Unable to parse']) 243 unknown_types[d] = (unknown_types.get(d, []) +
277 return unknown_types 244 [item.name or 'Unable to parse'])
245 return unknown_types
278 246
279 247
280 def ExtractJNINamespace(contents): 248 def ExtractJNINamespace(contents):
281 re_jni_namespace = re.compile('.*?@JNINamespace\("(.*?)"\)') 249 re_jni_namespace = re.compile('.*?@JNINamespace\("(.*?)"\)')
282 m = re.findall(re_jni_namespace, contents) 250 m = re.findall(re_jni_namespace, contents)
283 if not m: 251 if not m:
284 return '' 252 return ''
285 return m[0] 253 return m[0]
286 254
287 255
(...skipping 16 matching lines...) Expand all
304 '(?P<qualifiers>\w+\s\w+|\w+|\s+)\s*?native ' 272 '(?P<qualifiers>\w+\s\w+|\w+|\s+)\s*?native '
305 '(?P<return>\S*?) ' 273 '(?P<return>\S*?) '
306 '(?P<name>\w+?)\((?P<params>.*?)\);') 274 '(?P<name>\w+?)\((?P<params>.*?)\);')
307 for match in re.finditer(re_native, contents): 275 for match in re.finditer(re_native, contents):
308 native = NativeMethod( 276 native = NativeMethod(
309 static='static' in match.group('qualifiers'), 277 static='static' in match.group('qualifiers'),
310 java_class_name=match.group('java_class_name'), 278 java_class_name=match.group('java_class_name'),
311 native_class_name=match.group('native_class_name'), 279 native_class_name=match.group('native_class_name'),
312 return_type=match.group('return'), 280 return_type=match.group('return'),
313 name=match.group('name').replace('native', ''), 281 name=match.group('name').replace('native', ''),
314 params=ParseParams(match.group('params'))) 282 params=JniParams.Parse(match.group('params')))
315 natives += [native] 283 natives += [native]
316 return natives 284 return natives
317 285
318 286
319 def GetStaticCastForReturnType(return_type): 287 def GetStaticCastForReturnType(return_type):
320 if return_type == 'String': 288 if return_type == 'String':
321 return 'jstring' 289 return 'jstring'
322 return None 290 return None
323 291
324 292
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 Args: 334 Args:
367 name: string. 335 name: string.
368 params: list of Param. 336 params: list of Param.
369 return_type: string. 337 return_type: string.
370 338
371 Returns: 339 Returns:
372 A mangled name. 340 A mangled name.
373 """ 341 """
374 mangled_items = [] 342 mangled_items = []
375 for datatype in [return_type] + [x.datatype for x in params]: 343 for datatype in [return_type] + [x.datatype for x in params]:
376 mangled_items += [GetMangledParam(JavaParamToJni(datatype))] 344 mangled_items += [GetMangledParam(JniParams.JavaToJni(datatype))]
377 mangled_name = name + '_'.join(mangled_items) 345 mangled_name = name + '_'.join(mangled_items)
378 assert re.match(r'[0-9a-zA-Z_]+', mangled_name) 346 assert re.match(r'[0-9a-zA-Z_]+', mangled_name)
379 return mangled_name 347 return mangled_name
380 348
381 349
382 def MangleCalledByNatives(called_by_natives): 350 def MangleCalledByNatives(called_by_natives):
383 """Mangles all the overloads from the call_by_natives list.""" 351 """Mangles all the overloads from the call_by_natives list."""
384 method_counts = collections.defaultdict( 352 method_counts = collections.defaultdict(
385 lambda: collections.defaultdict(lambda: 0)) 353 lambda: collections.defaultdict(lambda: 0))
386 for called_by_native in called_by_natives: 354 for called_by_native in called_by_natives:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 """ 395 """
428 called_by_natives = [] 396 called_by_natives = []
429 for match in re.finditer(RE_CALLED_BY_NATIVE, contents): 397 for match in re.finditer(RE_CALLED_BY_NATIVE, contents):
430 called_by_natives += [CalledByNative( 398 called_by_natives += [CalledByNative(
431 system_class=False, 399 system_class=False,
432 unchecked='Unchecked' in match.group('Unchecked'), 400 unchecked='Unchecked' in match.group('Unchecked'),
433 static='static' in match.group('prefix'), 401 static='static' in match.group('prefix'),
434 java_class_name=match.group('annotation') or '', 402 java_class_name=match.group('annotation') or '',
435 return_type=match.group('return_type'), 403 return_type=match.group('return_type'),
436 name=match.group('name'), 404 name=match.group('name'),
437 params=ParseParams(match.group('params')))] 405 params=JniParams.Parse(match.group('params')))]
438 # Check for any @CalledByNative occurrences that weren't matched. 406 # Check for any @CalledByNative occurrences that weren't matched.
439 unmatched_lines = re.sub(RE_CALLED_BY_NATIVE, '', contents).split('\n') 407 unmatched_lines = re.sub(RE_CALLED_BY_NATIVE, '', contents).split('\n')
440 for line1, line2 in zip(unmatched_lines, unmatched_lines[1:]): 408 for line1, line2 in zip(unmatched_lines, unmatched_lines[1:]):
441 if '@CalledByNative' in line1: 409 if '@CalledByNative' in line1:
442 raise ParseError('could not parse @CalledByNative method signature', 410 raise ParseError('could not parse @CalledByNative method signature',
443 line1, line2) 411 line1, line2)
444 return MangleCalledByNatives(called_by_natives) 412 return MangleCalledByNatives(called_by_natives)
445 413
446 414
447 class JNIFromJavaP(object): 415 class JNIFromJavaP(object):
(...skipping 15 matching lines...) Expand all
463 match = re.match(re_method, content) 431 match = re.match(re_method, content)
464 if not match: 432 if not match:
465 continue 433 continue
466 self.called_by_natives += [CalledByNative( 434 self.called_by_natives += [CalledByNative(
467 system_class=True, 435 system_class=True,
468 unchecked=False, 436 unchecked=False,
469 static='static' in match.group('prefix'), 437 static='static' in match.group('prefix'),
470 java_class_name='', 438 java_class_name='',
471 return_type=match.group('return_type'), 439 return_type=match.group('return_type'),
472 name=match.group('name'), 440 name=match.group('name'),
473 params=ParseParams(match.group('params').replace('.', '/')))] 441 params=JniParams.Parse(match.group('params').replace('.', '/')))]
474 re_constructor = re.compile('.*? public ' + 442 re_constructor = re.compile('.*? public ' +
475 self.fully_qualified_class.replace('/', '.') + 443 self.fully_qualified_class.replace('/', '.') +
476 '\((?P<params>.*?)\)') 444 '\((?P<params>.*?)\)')
477 for content in contents[2:]: 445 for content in contents[2:]:
478 match = re.match(re_constructor, content) 446 match = re.match(re_constructor, content)
479 if not match: 447 if not match:
480 continue 448 continue
481 self.called_by_natives += [CalledByNative( 449 self.called_by_natives += [CalledByNative(
482 system_class=True, 450 system_class=True,
483 unchecked=False, 451 unchecked=False,
484 static=False, 452 static=False,
485 java_class_name='', 453 java_class_name='',
486 return_type=self.fully_qualified_class, 454 return_type=self.fully_qualified_class,
487 name='Constructor', 455 name='Constructor',
488 params=ParseParams(match.group('params').replace('.', '/')), 456 params=JniParams.Parse(match.group('params').replace('.', '/')),
489 is_constructor=True)] 457 is_constructor=True)]
490 self.called_by_natives = MangleCalledByNatives(self.called_by_natives) 458 self.called_by_natives = MangleCalledByNatives(self.called_by_natives)
491 self.inl_header_file_generator = InlHeaderFileGenerator( 459 self.inl_header_file_generator = InlHeaderFileGenerator(
492 self.namespace, self.fully_qualified_class, [], self.called_by_natives) 460 self.namespace, self.fully_qualified_class, [], self.called_by_natives)
493 461
494 def GetContent(self): 462 def GetContent(self):
495 return self.inl_header_file_generator.GetContent() 463 return self.inl_header_file_generator.GetContent()
496 464
497 @staticmethod 465 @staticmethod
498 def CreateFromClass(class_file, namespace): 466 def CreateFromClass(class_file, namespace):
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 """Generates an inline header file for JNI integration.""" 522 """Generates an inline header file for JNI integration."""
555 523
556 def __init__(self, namespace, fully_qualified_class, natives, 524 def __init__(self, namespace, fully_qualified_class, natives,
557 called_by_natives): 525 called_by_natives):
558 self.namespace = namespace 526 self.namespace = namespace
559 self.fully_qualified_class = fully_qualified_class 527 self.fully_qualified_class = fully_qualified_class
560 self.class_name = self.fully_qualified_class.split('/')[-1] 528 self.class_name = self.fully_qualified_class.split('/')[-1]
561 self.natives = natives 529 self.natives = natives
562 self.called_by_natives = called_by_natives 530 self.called_by_natives = called_by_natives
563 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' 531 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI'
564 unknown_datatypes = GetUnknownDatatypes(self.natives + 532 JniParams.CheckUnknownDatatypes(self.fully_qualified_class,
565 self.called_by_natives) 533 self.natives + self.called_by_natives)
566 if unknown_datatypes:
567 msg = ('There are a few unknown datatypes in %s' %
568 self.fully_qualified_class)
569 msg += '\nPlease, edit %s' % sys.argv[0]
570 msg += '\nand add the java type to JavaParamToJni()\n'
571 for unknown_datatype in unknown_datatypes:
572 msg += '\n%s in methods:\n' % unknown_datatype
573 msg += '\n '.join(unknown_datatypes[unknown_datatype])
574 raise SyntaxError(msg)
575 534
576 def GetContent(self): 535 def GetContent(self):
577 """Returns the content of the JNI binding file.""" 536 """Returns the content of the JNI binding file."""
578 template = Template("""\ 537 template = Template("""\
579 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 538 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
580 // Use of this source code is governed by a BSD-style license that can be 539 // Use of this source code is governed by a BSD-style license that can be
581 // found in the LICENSE file. 540 // found in the LICENSE file.
582 541
583 542
584 // This file is autogenerated by 543 // This file is autogenerated by
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 values['FUNCTION_HEADER'] = ( 817 values['FUNCTION_HEADER'] = (
859 function_header_with_unused_template.substitute(values)) 818 function_header_with_unused_template.substitute(values))
860 else: 819 else:
861 values['FUNCTION_HEADER'] = function_header_template.substitute(values) 820 values['FUNCTION_HEADER'] = function_header_template.substitute(values)
862 return template.substitute(values) 821 return template.substitute(values)
863 822
864 def GetKMethodArrayEntry(self, native): 823 def GetKMethodArrayEntry(self, native):
865 template = Template("""\ 824 template = Template("""\
866 { "native${NAME}", ${JNI_SIGNATURE}, reinterpret_cast<void*>(${NAME}) },""") 825 { "native${NAME}", ${JNI_SIGNATURE}, reinterpret_cast<void*>(${NAME}) },""")
867 values = {'NAME': native.name, 826 values = {'NAME': native.name,
868 'JNI_SIGNATURE': JniSignature(native.params, native.return_type, 827 'JNI_SIGNATURE': JniParams.Signature(native.params,
869 True)} 828 native.return_type,
829 True)}
870 return template.substitute(values) 830 return template.substitute(values)
871 831
872 def GetUniqueClasses(self, origin): 832 def GetUniqueClasses(self, origin):
873 ret = {self.class_name: self.fully_qualified_class} 833 ret = {self.class_name: self.fully_qualified_class}
874 for entry in origin: 834 for entry in origin:
875 class_name = self.class_name 835 class_name = self.class_name
876 jni_class_path = self.fully_qualified_class 836 jni_class_path = self.fully_qualified_class
877 if entry.java_class_name: 837 if entry.java_class_name:
878 class_name = entry.java_class_name 838 class_name = entry.java_class_name
879 jni_class_path = self.fully_qualified_class + '$' + class_name 839 jni_class_path = self.fully_qualified_class + '$' + class_name
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 jni_name = called_by_native.name 890 jni_name = called_by_native.name
931 jni_return_type = called_by_native.return_type 891 jni_return_type = called_by_native.return_type
932 if called_by_native.is_constructor: 892 if called_by_native.is_constructor:
933 jni_name = '<init>' 893 jni_name = '<init>'
934 jni_return_type = 'void' 894 jni_return_type = 'void'
935 values = { 895 values = {
936 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, 896 'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
937 'JNI_NAME': jni_name, 897 'JNI_NAME': jni_name,
938 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 898 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
939 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE', 899 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE',
940 'JNI_SIGNATURE': JniSignature(called_by_native.params, 900 'JNI_SIGNATURE': JniParams.Signature(called_by_native.params,
941 jni_return_type, 901 jni_return_type,
942 True) 902 True)
943 } 903 }
944 return template.substitute(values) 904 return template.substitute(values)
945 905
946 906
947 def WrapOutput(output): 907 def WrapOutput(output):
948 ret = [] 908 ret = []
949 for line in output.splitlines(): 909 for line in output.splitlines():
950 # Do not wrap lines under 80 characters or preprocessor directives. 910 # Do not wrap lines under 80 characters or preprocessor directives.
951 if len(line) < 80 or line.lstrip()[:1] == '#': 911 if len(line) < 80 or line.lstrip()[:1] == '#':
952 stripped = line.rstrip() 912 stripped = line.rstrip()
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 option_parser.add_option('-n', dest='namespace', 987 option_parser.add_option('-n', dest='namespace',
1028 help='Uses as a namespace in the generated header,' 988 help='Uses as a namespace in the generated header,'
1029 ' instead of the javap class name.') 989 ' instead of the javap class name.')
1030 option_parser.add_option('--input_file', 990 option_parser.add_option('--input_file',
1031 help='Single input file name. The output file name ' 991 help='Single input file name. The output file name '
1032 'will be derived from it. Must be used with ' 992 'will be derived from it. Must be used with '
1033 '--output_dir.') 993 '--output_dir.')
1034 option_parser.add_option('--output_dir', 994 option_parser.add_option('--output_dir',
1035 help='The output directory. Must be used with ' 995 help='The output directory. Must be used with '
1036 '--input') 996 '--input')
997 option_parser.add_option('--external_param_list',
998 help='A file name containing a list with extra '
999 'fully-qualified param names. Can be used multiple '
1000 'times.',
1001 action='append')
1037 options, args = option_parser.parse_args(argv) 1002 options, args = option_parser.parse_args(argv)
1003 JniParams.ReadExternalParamList(options.external_param_list)
1038 if options.jar_file: 1004 if options.jar_file:
1039 input_file = ExtractJarInputFile(options.jar_file, options.input_file, 1005 input_file = ExtractJarInputFile(options.jar_file, options.input_file,
1040 options.output_dir) 1006 options.output_dir)
1041 else: 1007 else:
1042 input_file = options.input_file 1008 input_file = options.input_file
1043 output_file = None 1009 output_file = None
1044 if options.output_dir: 1010 if options.output_dir:
1045 root_name = os.path.splitext(os.path.basename(input_file))[0] 1011 root_name = os.path.splitext(os.path.basename(input_file))[0]
1046 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1012 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1047 GenerateJNIHeader(input_file, output_file, options.namespace) 1013 GenerateJNIHeader(input_file, output_file, options.namespace)
1048 1014
1049 1015
1050 if __name__ == '__main__': 1016 if __name__ == '__main__':
1051 sys.exit(main(sys.argv)) 1017 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « base/android/jni_generator/class_list.jni ('k') | base/android/jni_generator/jni_generator_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698