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

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: 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 if not prefix in signature_line:
148 return None
joth 2013/10/24 19:18:13 is missing the "Signature:" prefix an allowable si
bulach 2013/10/25 08:45:49 good point! turns out there's a "-s" parameter to
149 return '"%s"' % signature_line[signature_line.index(prefix) + len(prefix):]
150
151 @staticmethod
144 def JavaToJni(param): 152 def JavaToJni(param):
145 """Converts a java param into a JNI signature type.""" 153 """Converts a java param into a JNI signature type."""
146 pod_param_map = { 154 pod_param_map = {
147 'int': 'I', 155 'int': 'I',
148 'boolean': 'Z', 156 'boolean': 'Z',
149 'char': 'C', 157 'char': 'C',
150 'short': 'S', 158 'short': 'S',
151 'long': 'J', 159 'long': 'J',
152 'double': 'D', 160 'double': 'D',
153 'float': 'F', 161 '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 467 # 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. 468 # 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] 469 self.fully_qualified_class = self.fully_qualified_class.split('<', 1)[0]
462 JniParams.SetFullyQualifiedClass(self.fully_qualified_class) 470 JniParams.SetFullyQualifiedClass(self.fully_qualified_class)
463 self.java_class_name = self.fully_qualified_class.split('/')[-1] 471 self.java_class_name = self.fully_qualified_class.split('/')[-1]
464 if not self.namespace: 472 if not self.namespace:
465 self.namespace = 'JNI_' + self.java_class_name 473 self.namespace = 'JNI_' + self.java_class_name
466 re_method = re.compile('(?P<prefix>.*?)(?P<return_type>\S+?) (?P<name>\w+?)' 474 re_method = re.compile('(?P<prefix>.*?)(?P<return_type>\S+?) (?P<name>\w+?)'
467 '\((?P<params>.*?)\)') 475 '\((?P<params>.*?)\)')
468 self.called_by_natives = [] 476 self.called_by_natives = []
469 for content in contents[2:]: 477 for lineno, content in enumerate(contents[2:], 2):
470 match = re.match(re_method, content) 478 match = re.match(re_method, content)
471 if not match: 479 if not match:
472 continue 480 continue
473 self.called_by_natives += [CalledByNative( 481 self.called_by_natives += [CalledByNative(
474 system_class=True, 482 system_class=True,
475 unchecked=False, 483 unchecked=False,
476 static='static' in match.group('prefix'), 484 static='static' in match.group('prefix'),
477 java_class_name='', 485 java_class_name='',
478 return_type=match.group('return_type').replace('.', '/'), 486 return_type=match.group('return_type').replace('.', '/'),
479 name=match.group('name'), 487 name=match.group('name'),
480 params=JniParams.Parse(match.group('params').replace('.', '/')))] 488 params=JniParams.Parse(match.group('params').replace('.', '/')),
489 signature=JniParams.ParseJavaPSignature(contents[lineno + 1]))]
481 re_constructor = re.compile('.*? public ' + 490 re_constructor = re.compile('.*? public ' +
482 self.fully_qualified_class.replace('/', '.') + 491 self.fully_qualified_class.replace('/', '.') +
483 '\((?P<params>.*?)\)') 492 '\((?P<params>.*?)\)')
484 for content in contents[2:]: 493 for lineno, content in enumerate(contents[2:], 2):
485 match = re.match(re_constructor, content) 494 match = re.match(re_constructor, content)
486 if not match: 495 if not match:
487 continue 496 continue
488 self.called_by_natives += [CalledByNative( 497 self.called_by_natives += [CalledByNative(
489 system_class=True, 498 system_class=True,
490 unchecked=False, 499 unchecked=False,
491 static=False, 500 static=False,
492 java_class_name='', 501 java_class_name='',
493 return_type=self.fully_qualified_class, 502 return_type=self.fully_qualified_class,
494 name='Constructor', 503 name='Constructor',
495 params=JniParams.Parse(match.group('params').replace('.', '/')), 504 params=JniParams.Parse(match.group('params').replace('.', '/')),
505 signature=JniParams.ParseJavaPSignature(contents[lineno + 1]),
496 is_constructor=True)] 506 is_constructor=True)]
497 self.called_by_natives = MangleCalledByNatives(self.called_by_natives) 507 self.called_by_natives = MangleCalledByNatives(self.called_by_natives)
498 self.inl_header_file_generator = InlHeaderFileGenerator( 508 self.inl_header_file_generator = InlHeaderFileGenerator(
499 self.namespace, self.fully_qualified_class, [], 509 self.namespace, self.fully_qualified_class, [],
500 self.called_by_natives, options) 510 self.called_by_natives, options)
501 511
502 def GetContent(self): 512 def GetContent(self):
503 return self.inl_header_file_generator.GetContent() 513 return self.inl_header_file_generator.GetContent()
504 514
505 @staticmethod 515 @staticmethod
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 env, g_${JAVA_CLASS}_clazz, 934 env, g_${JAVA_CLASS}_clazz,
925 "${JNI_NAME}", 935 "${JNI_NAME}",
926 ${JNI_SIGNATURE}, 936 ${JNI_SIGNATURE},
927 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME}); 937 &g_${JAVA_CLASS}_${METHOD_ID_VAR_NAME});
928 """) 938 """)
929 jni_name = called_by_native.name 939 jni_name = called_by_native.name
930 jni_return_type = called_by_native.return_type 940 jni_return_type = called_by_native.return_type
931 if called_by_native.is_constructor: 941 if called_by_native.is_constructor:
932 jni_name = '<init>' 942 jni_name = '<init>'
933 jni_return_type = 'void' 943 jni_return_type = 'void'
944 if called_by_native.signature:
945 signature = called_by_native.signature
946 else:
947 signature = JniParams.Signature(called_by_native.params,
948 jni_return_type,
949 True)
934 values = { 950 values = {
935 'JAVA_CLASS': called_by_native.java_class_name or self.class_name, 951 'JAVA_CLASS': called_by_native.java_class_name or self.class_name,
936 'JNI_NAME': jni_name, 952 'JNI_NAME': jni_name,
937 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name, 953 'METHOD_ID_VAR_NAME': called_by_native.method_id_var_name,
938 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE', 954 'STATIC': 'STATIC' if called_by_native.static else 'INSTANCE',
939 'JNI_SIGNATURE': JniParams.Signature(called_by_native.params, 955 'JNI_SIGNATURE': signature,
940 jni_return_type,
941 True)
942 } 956 }
943 return template.substitute(values) 957 return template.substitute(values)
944 958
945 959
946 def WrapOutput(output): 960 def WrapOutput(output):
947 ret = [] 961 ret = []
948 for line in output.splitlines(): 962 for line in output.splitlines():
949 # Do not wrap lines under 80 characters or preprocessor directives. 963 # Do not wrap lines under 80 characters or preprocessor directives.
950 if len(line) < 80 or line.lstrip()[:1] == '#': 964 if len(line) < 80 or line.lstrip()[:1] == '#':
951 stripped = line.rstrip() 965 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] 1090 root_name = os.path.splitext(os.path.basename(input_file))[0]
1077 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1091 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1078 if options.jarjar: 1092 if options.jarjar:
1079 with open(options.jarjar) as f: 1093 with open(options.jarjar) as f:
1080 JniParams.SetJarJarMappings(f.read()) 1094 JniParams.SetJarJarMappings(f.read())
1081 GenerateJNIHeader(input_file, output_file, options) 1095 GenerateJNIHeader(input_file, output_file, options)
1082 1096
1083 1097
1084 if __name__ == '__main__': 1098 if __name__ == '__main__':
1085 sys.exit(main(sys.argv)) 1099 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