Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 625 match = re.match(re_constant_field, content) | 625 match = re.match(re_constant_field, content) |
| 626 if not match: | 626 if not match: |
| 627 continue | 627 continue |
| 628 value = re.match(re_constant_field_value, contents[lineno + 2]) | 628 value = re.match(re_constant_field_value, contents[lineno + 2]) |
| 629 if not value: | 629 if not value: |
| 630 value = re.match(re_constant_field_value, contents[lineno + 3]) | 630 value = re.match(re_constant_field_value, contents[lineno + 3]) |
| 631 if value: | 631 if value: |
| 632 self.constant_fields.append( | 632 self.constant_fields.append( |
| 633 ConstantField(name=match.group('name'), | 633 ConstantField(name=match.group('name'), |
| 634 value=value.group('value'))) | 634 value=value.group('value'))) |
| 635 | |
| 636 self.inl_header_file_generator = InlHeaderFileGenerator( | 635 self.inl_header_file_generator = InlHeaderFileGenerator( |
| 637 self.namespace, self.fully_qualified_class, [], | 636 self.namespace, self.fully_qualified_class, [], self.called_by_natives, |
| 638 self.called_by_natives, self.constant_fields, options) | 637 self.constant_fields, options) |
| 639 | 638 |
| 640 def GetContent(self): | 639 def GetContent(self): |
| 641 return self.inl_header_file_generator.GetContent() | 640 return self.inl_header_file_generator.GetContent() |
| 642 | 641 |
| 643 @staticmethod | 642 @staticmethod |
| 644 def CreateFromClass(class_file, options): | 643 def CreateFromClass(class_file, options): |
| 645 class_name = os.path.splitext(os.path.basename(class_file))[0] | 644 class_name = os.path.splitext(os.path.basename(class_file))[0] |
| 646 p = subprocess.Popen(args=[options.javap, '-c', '-verbose', | 645 p = subprocess.Popen(args=[options.javap, '-c', '-verbose', |
| 647 '-s', class_name], | 646 '-s', class_name], |
| 648 cwd=os.path.dirname(class_file), | 647 cwd=os.path.dirname(class_file), |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 662 r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', | 661 r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"', |
| 663 re.DOTALL | re.MULTILINE) | 662 re.DOTALL | re.MULTILINE) |
| 664 | 663 |
| 665 def __init__(self, contents, fully_qualified_class, options): | 664 def __init__(self, contents, fully_qualified_class, options): |
| 666 contents = self._RemoveComments(contents) | 665 contents = self._RemoveComments(contents) |
| 667 JniParams.SetFullyQualifiedClass(fully_qualified_class) | 666 JniParams.SetFullyQualifiedClass(fully_qualified_class) |
| 668 JniParams.ExtractImportsAndInnerClasses(contents) | 667 JniParams.ExtractImportsAndInnerClasses(contents) |
| 669 jni_namespace = ExtractJNINamespace(contents) or options.namespace | 668 jni_namespace = ExtractJNINamespace(contents) or options.namespace |
| 670 natives = ExtractNatives(contents, options.ptr_type) | 669 natives = ExtractNatives(contents, options.ptr_type) |
| 671 called_by_natives = ExtractCalledByNatives(contents) | 670 called_by_natives = ExtractCalledByNatives(contents) |
| 671 maindex = '@MainDex' in contents | |
|
Torne
2016/12/14 11:40:24
The other Extract* functions are doing more than j
| |
| 672 if len(natives) == 0 and len(called_by_natives) == 0: | 672 if len(natives) == 0 and len(called_by_natives) == 0: |
| 673 raise SyntaxError('Unable to find any JNI methods for %s.' % | 673 raise SyntaxError('Unable to find any JNI methods for %s.' % |
| 674 fully_qualified_class) | 674 fully_qualified_class) |
| 675 inl_header_file_generator = InlHeaderFileGenerator( | 675 inl_header_file_generator = InlHeaderFileGenerator( |
| 676 jni_namespace, fully_qualified_class, natives, called_by_natives, | 676 jni_namespace, fully_qualified_class, natives, called_by_natives, [], |
| 677 [], options) | 677 options, maindex) |
| 678 self.content = inl_header_file_generator.GetContent() | 678 self.content = inl_header_file_generator.GetContent() |
| 679 | 679 |
| 680 @classmethod | 680 @classmethod |
| 681 def _RemoveComments(cls, contents): | 681 def _RemoveComments(cls, contents): |
| 682 # We need to support both inline and block comments, and we need to handle | 682 # We need to support both inline and block comments, and we need to handle |
| 683 # strings that contain '//' or '/*'. | 683 # strings that contain '//' or '/*'. |
| 684 # TODO(bulach): This is a bit hacky. It would be cleaner to use a real Java | 684 # TODO(bulach): This is a bit hacky. It would be cleaner to use a real Java |
| 685 # parser. Maybe we could ditch JNIFromJavaSource and just always use | 685 # parser. Maybe we could ditch JNIFromJavaSource and just always use |
| 686 # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT. | 686 # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT. |
| 687 # http://code.google.com/p/chromium/issues/detail?id=138941 | 687 # http://code.google.com/p/chromium/issues/detail?id=138941 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 703 contents = file(java_file_name).read() | 703 contents = file(java_file_name).read() |
| 704 fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name, | 704 fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name, |
| 705 contents) | 705 contents) |
| 706 return JNIFromJavaSource(contents, fully_qualified_class, options) | 706 return JNIFromJavaSource(contents, fully_qualified_class, options) |
| 707 | 707 |
| 708 | 708 |
| 709 class InlHeaderFileGenerator(object): | 709 class InlHeaderFileGenerator(object): |
| 710 """Generates an inline header file for JNI integration.""" | 710 """Generates an inline header file for JNI integration.""" |
| 711 | 711 |
| 712 def __init__(self, namespace, fully_qualified_class, natives, | 712 def __init__(self, namespace, fully_qualified_class, natives, |
| 713 called_by_natives, constant_fields, options): | 713 called_by_natives, constant_fields, options, maindex=False): |
| 714 self.namespace = namespace | 714 self.namespace = namespace |
| 715 self.fully_qualified_class = fully_qualified_class | 715 self.fully_qualified_class = fully_qualified_class |
| 716 self.class_name = self.fully_qualified_class.split('/')[-1] | 716 self.class_name = self.fully_qualified_class.split('/')[-1] |
| 717 self.natives = natives | 717 self.natives = natives |
| 718 self.called_by_natives = called_by_natives | 718 self.called_by_natives = called_by_natives |
| 719 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' | 719 self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI' |
| 720 self.constant_fields = constant_fields | 720 self.constant_fields = constant_fields |
| 721 self.maindex = maindex | |
| 721 self.options = options | 722 self.options = options |
| 722 | 723 |
| 723 | 724 |
| 724 def GetContent(self): | 725 def GetContent(self): |
| 725 """Returns the content of the JNI binding file.""" | 726 """Returns the content of the JNI binding file.""" |
| 726 template = Template("""\ | 727 template = Template("""\ |
| 727 // Copyright 2014 The Chromium Authors. All rights reserved. | 728 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 728 // Use of this source code is governed by a BSD-style license that can be | 729 // Use of this source code is governed by a BSD-style license that can be |
| 729 // found in the LICENSE file. | 730 // found in the LICENSE file. |
| 730 | 731 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 ${NATIVES} | 858 ${NATIVES} |
| 858 return true; | 859 return true; |
| 859 } | 860 } |
| 860 """) | 861 """) |
| 861 signature = 'static bool RegisterNativesImpl(JNIEnv* env)' | 862 signature = 'static bool RegisterNativesImpl(JNIEnv* env)' |
| 862 early_exit = '' | 863 early_exit = '' |
| 863 if self.options.native_exports_optional: | 864 if self.options.native_exports_optional: |
| 864 early_exit = """\ | 865 early_exit = """\ |
| 865 if (base::android::IsManualJniRegistrationDisabled()) return true; | 866 if (base::android::IsManualJniRegistrationDisabled()) return true; |
| 866 """ | 867 """ |
| 868 if not self.maindex: | |
| 869 early_exit += """\ | |
| 870 base::android::LibraryProcessType proc_type = | |
|
Torne
2016/12/14 11:40:24
Can you put this in jni_generator_helper.h as an i
| |
| 871 base::android::GetLibraryProcessType(env); | |
|
Torne
2016/12/14 11:40:24
GetLibraryProcessType is a JNI call; if we're goin
| |
| 872 if (proc_type != base::android::PROCESS_BROWSER && | |
| 873 proc_type != base::android::PROCESS_UNINITIALIZED) { | |
|
Torne
2016/12/14 11:40:25
Is there really a case where the process type is u
| |
| 874 return true; | |
| 875 } | |
| 876 """ | |
| 867 | 877 |
| 868 values = {'REGISTER_NATIVES_SIGNATURE': signature, | 878 values = {'REGISTER_NATIVES_SIGNATURE': signature, |
| 869 'EARLY_EXIT': early_exit, | 879 'EARLY_EXIT': early_exit, |
| 870 'NATIVES': natives, | 880 'NATIVES': natives, |
| 871 } | 881 } |
| 872 | 882 |
| 873 return template.substitute(values) | 883 return template.substitute(values) |
| 874 | 884 |
| 875 def GetRegisterNativesImplString(self): | 885 def GetRegisterNativesImplString(self): |
| 876 """Returns the shared implementation for RegisterNatives.""" | 886 """Returns the shared implementation for RegisterNatives.""" |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1393 root_name = os.path.splitext(os.path.basename(input_file))[0] | 1403 root_name = os.path.splitext(os.path.basename(input_file))[0] |
| 1394 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' | 1404 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' |
| 1395 GenerateJNIHeader(input_file, output_file, options) | 1405 GenerateJNIHeader(input_file, output_file, options) |
| 1396 | 1406 |
| 1397 if options.depfile: | 1407 if options.depfile: |
| 1398 build_utils.WriteDepfile(options.depfile, output_file) | 1408 build_utils.WriteDepfile(options.depfile, output_file) |
| 1399 | 1409 |
| 1400 | 1410 |
| 1401 if __name__ == '__main__': | 1411 if __name__ == '__main__': |
| 1402 sys.exit(main(sys.argv)) | 1412 sys.exit(main(sys.argv)) |
| OLD | NEW |