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

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

Issue 40523002: Android: fixes for JNI with javap for java7. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Mandatory Signature: Created 7 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
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 """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.
7 If you change this, please run and update the tests.""" 7 If you change this, please run and update the tests."""
8 8
9 import collections 9 import collections
10 import errno 10 import errno
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 69
70 def __init__(self, **kwargs): 70 def __init__(self, **kwargs):
71 self.system_class = kwargs['system_class'] 71 self.system_class = kwargs['system_class']
72 self.unchecked = kwargs['unchecked'] 72 self.unchecked = kwargs['unchecked']
73 self.static = kwargs['static'] 73 self.static = kwargs['static']
74 self.java_class_name = kwargs['java_class_name'] 74 self.java_class_name = kwargs['java_class_name']
75 self.return_type = kwargs['return_type'] 75 self.return_type = kwargs['return_type']
76 self.name = kwargs['name'] 76 self.name = kwargs['name']
77 self.params = kwargs['params'] 77 self.params = kwargs['params']
78 self.method_id_var_name = kwargs.get('method_id_var_name', None) 78 self.method_id_var_name = kwargs.get('method_id_var_name', None)
79 self.signature = kwargs.get('signature')
79 self.is_constructor = kwargs.get('is_constructor', False) 80 self.is_constructor = kwargs.get('is_constructor', False)
80 self.env_call = GetEnvCall(self.is_constructor, self.static, 81 self.env_call = GetEnvCall(self.is_constructor, self.static,
81 self.return_type) 82 self.return_type)
82 self.static_cast = GetStaticCastForReturnType(self.return_type) 83 self.static_cast = GetStaticCastForReturnType(self.return_type)
83 84
84 85
85 def JavaDataTypeToC(java_type): 86 def JavaDataTypeToC(java_type):
86 """Returns a C datatype for the given java type.""" 87 """Returns a C datatype for the given java type."""
87 java_pod_type_map = { 88 java_pod_type_map = {
88 'int': 'jint', 89 'int': 'jint',
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 JniParams._imports += ['L' + match.group('class').replace('.', '/')] 135 JniParams._imports += ['L' + match.group('class').replace('.', '/')]
135 136
136 re_inner = re.compile(r'(class|interface)\s+?(?P<name>\w+?)\W') 137 re_inner = re.compile(r'(class|interface)\s+?(?P<name>\w+?)\W')
137 for match in re.finditer(re_inner, contents): 138 for match in re.finditer(re_inner, contents):
138 inner = match.group('name') 139 inner = match.group('name')
139 if not JniParams._fully_qualified_class.endswith(inner): 140 if not JniParams._fully_qualified_class.endswith(inner):
140 JniParams._inner_classes += [JniParams._fully_qualified_class + '$' + 141 JniParams._inner_classes += [JniParams._fully_qualified_class + '$' +
141 inner] 142 inner]
142 143
143 @staticmethod 144 @staticmethod
145 def ParseJavaPSignature(signature_line):
146 prefix = 'Signature: '
147 return '"%s"' % signature_line[signature_line.index(prefix) + len(prefix):]
148
149 @staticmethod
144 def JavaToJni(param): 150 def JavaToJni(param):
145 """Converts a java param into a JNI signature type.""" 151 """Converts a java param into a JNI signature type."""
146 pod_param_map = { 152 pod_param_map = {
147 'int': 'I', 153 'int': 'I',
148 'boolean': 'Z', 154 'boolean': 'Z',
149 'char': 'C', 155 'char': 'C',
150 'short': 'S', 156 'short': 'S',
151 'long': 'J', 157 'long': 'J',
152 'double': 'D', 158 'double': 'D',
153 'float': 'F', 159 'float': 'F',
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 # Java 7's javap includes type parameters in output, like HashSet<T>. Strip 465 # Java 7's javap includes type parameters in output, like HashSet<T>. Strip
460 # away the <...> and use the raw class name that Java 6 would've given us. 466 # away the <...> and use the raw class name that Java 6 would've given us.
461 self.fully_qualified_class = self.fully_qualified_class.split('<', 1)[0] 467 self.fully_qualified_class = self.fully_qualified_class.split('<', 1)[0]
462 JniParams.SetFullyQualifiedClass(self.fully_qualified_class) 468 JniParams.SetFullyQualifiedClass(self.fully_qualified_class)
463 self.java_class_name = self.fully_qualified_class.split('/')[-1] 469 self.java_class_name = self.fully_qualified_class.split('/')[-1]
464 if not self.namespace: 470 if not self.namespace:
465 self.namespace = 'JNI_' + self.java_class_name 471 self.namespace = 'JNI_' + self.java_class_name
466 re_method = re.compile('(?P<prefix>.*?)(?P<return_type>\S+?) (?P<name>\w+?)' 472 re_method = re.compile('(?P<prefix>.*?)(?P<return_type>\S+?) (?P<name>\w+?)'
467 '\((?P<params>.*?)\)') 473 '\((?P<params>.*?)\)')
468 self.called_by_natives = [] 474 self.called_by_natives = []
469 for content in contents[2:]: 475 for lineno, content in enumerate(contents[2:], 2):
470 match = re.match(re_method, content) 476 match = re.match(re_method, content)
471 if not match: 477 if not match:
472 continue 478 continue
473 self.called_by_natives += [CalledByNative( 479 self.called_by_natives += [CalledByNative(
474 system_class=True, 480 system_class=True,
475 unchecked=False, 481 unchecked=False,
476 static='static' in match.group('prefix'), 482 static='static' in match.group('prefix'),
477 java_class_name='', 483 java_class_name='',
478 return_type=match.group('return_type').replace('.', '/'), 484 return_type=match.group('return_type').replace('.', '/'),
479 name=match.group('name'), 485 name=match.group('name'),
480 params=JniParams.Parse(match.group('params').replace('.', '/')))] 486 params=JniParams.Parse(match.group('params').replace('.', '/')),
481 re_constructor = re.compile('.*? public ' + 487 signature=JniParams.ParseJavaPSignature(contents[lineno + 1]))]
488 re_constructor = re.compile('(.*?)public ' +
482 self.fully_qualified_class.replace('/', '.') + 489 self.fully_qualified_class.replace('/', '.') +
483 '\((?P<params>.*?)\)') 490 '\((?P<params>.*?)\)')
484 for content in contents[2:]: 491 for lineno, content in enumerate(contents[2:], 2):
485 match = re.match(re_constructor, content) 492 match = re.match(re_constructor, content)
486 if not match: 493 if not match:
487 continue 494 continue
488 self.called_by_natives += [CalledByNative( 495 self.called_by_natives += [CalledByNative(
489 system_class=True, 496 system_class=True,
490 unchecked=False, 497 unchecked=False,
491 static=False, 498 static=False,
492 java_class_name='', 499 java_class_name='',
493 return_type=self.fully_qualified_class, 500 return_type=self.fully_qualified_class,
494 name='Constructor', 501 name='Constructor',
495 params=JniParams.Parse(match.group('params').replace('.', '/')), 502 params=JniParams.Parse(match.group('params').replace('.', '/')),
503 signature=JniParams.ParseJavaPSignature(contents[lineno + 1]),
496 is_constructor=True)] 504 is_constructor=True)]
497 self.called_by_natives = MangleCalledByNatives(self.called_by_natives) 505 self.called_by_natives = MangleCalledByNatives(self.called_by_natives)
498 self.inl_header_file_generator = InlHeaderFileGenerator( 506 self.inl_header_file_generator = InlHeaderFileGenerator(
499 self.namespace, self.fully_qualified_class, [], 507 self.namespace, self.fully_qualified_class, [],
500 self.called_by_natives, options) 508 self.called_by_natives, options)
501 509
502 def GetContent(self): 510 def GetContent(self):
503 return self.inl_header_file_generator.GetContent() 511 return self.inl_header_file_generator.GetContent()
504 512
505 @staticmethod 513 @staticmethod
506 def CreateFromClass(class_file, options): 514 def CreateFromClass(class_file, options):
507 class_name = os.path.splitext(os.path.basename(class_file))[0] 515 class_name = os.path.splitext(os.path.basename(class_file))[0]
508 p = subprocess.Popen(args=['javap', class_name], 516 p = subprocess.Popen(args=['javap', '-s', class_name],
509 cwd=os.path.dirname(class_file), 517 cwd=os.path.dirname(class_file),
510 stdout=subprocess.PIPE, 518 stdout=subprocess.PIPE,
511 stderr=subprocess.PIPE) 519 stderr=subprocess.PIPE)
512 stdout, _ = p.communicate() 520 stdout, _ = p.communicate()
513 jni_from_javap = JNIFromJavaP(stdout.split('\n'), options) 521 jni_from_javap = JNIFromJavaP(stdout.split('\n'), options)
514 return jni_from_javap 522 return jni_from_javap
515 523
516 524
517 class JNIFromJavaSource(object): 525 class JNIFromJavaSource(object):
518 """Uses the given java source file to generate the JNI header file.""" 526 """Uses the given java source file to generate the JNI header file."""
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 env, g_${JAVA_CLASS}_clazz, 932 env, g_${JAVA_CLASS}_clazz,
925 "${JNI_NAME}", 933 "${JNI_NAME}",
926 ${JNI_SIGNATURE}, 934 ${JNI_SIGNATURE},
927 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); 935 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME});
928 """) 936 """)
929 jni_name = called_by_native.name 937 jni_name = called_by_native.name
930 jni_return_type = called_by_native.return_type 938 jni_return_type = called_by_native.return_type
931 if called_by_native.is_constructor: 939 if called_by_native.is_constructor:
932 jni_name = '<init>' 940 jni_name = '<init>'
933 jni_return_type = 'void' 941 jni_return_type = 'void'
942 if called_by_native.signature:
943 signature = called_by_native.signature
944 else:
945 signature = JniParams.Signature(called_by_native.params,
946 jni_return_type,
947 True)
934 values = { 948 values = {
935 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, 949 'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
936 'JNI_NAME': jni_name, 950 'JNI_NAME': jni_name,
937 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 951 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
938 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE', 952 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE',
939 'JNI_SIGNATURE': JniParams.Signature(called_by_native.params, 953 'JNI_SIGNATURE': signature,
940 jni_return_type,
941 True)
942 } 954 }
943 return template.substitute(values) 955 return template.substitute(values)
944 956
945 957
946 def WrapOutput(output): 958 def WrapOutput(output):
947 ret = [] 959 ret = []
948 for line in output.splitlines(): 960 for line in output.splitlines():
949 # Do not wrap lines under 80 characters or preprocessor directives. 961 # Do not wrap lines under 80 characters or preprocessor directives.
950 if len(line) < 80 or line.lstrip()[:1] == '#': 962 if len(line) < 80 or line.lstrip()[:1] == '#':
951 stripped = line.rstrip() 963 stripped = line.rstrip()
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 root_name = os.path.splitext(os.path.basename(input_file))[0] 1088 root_name = os.path.splitext(os.path.basename(input_file))[0]
1077 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1089 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1078 if options.jarjar: 1090 if options.jarjar:
1079 with open(options.jarjar) as f: 1091 with open(options.jarjar) as f:
1080 JniParams.SetJarJarMappings(f.read()) 1092 JniParams.SetJarJarMappings(f.read())
1081 GenerateJNIHeader(input_file, output_file, options) 1093 GenerateJNIHeader(input_file, output_file, options)
1082 1094
1083 1095
1084 if __name__ == '__main__': 1096 if __name__ == '__main__':
1085 sys.exit(main(sys.argv)) 1097 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | base/android/jni_generator/jni_generator_tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698