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 |