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

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

Issue 227303003: android: Don't use cpp to strip comments in jni_generator. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Completely different approach Created 6 years, 8 months 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 | no next file » | 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 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 stderr=subprocess.PIPE) 574 stderr=subprocess.PIPE)
575 stdout, _ = p.communicate() 575 stdout, _ = p.communicate()
576 jni_from_javap = JNIFromJavaP(stdout.split('\n'), options) 576 jni_from_javap = JNIFromJavaP(stdout.split('\n'), options)
577 return jni_from_javap 577 return jni_from_javap
578 578
579 579
580 class JNIFromJavaSource(object): 580 class JNIFromJavaSource(object):
581 """Uses the given java source file to generate the JNI header file.""" 581 """Uses the given java source file to generate the JNI header file."""
582 582
583 def __init__(self, contents, fully_qualified_class, options): 583 def __init__(self, contents, fully_qualified_class, options):
584 contents = self._RemoveComments(contents, options) 584 contents = self._RemoveComments(contents)
585 JniParams.SetFullyQualifiedClass(fully_qualified_class) 585 JniParams.SetFullyQualifiedClass(fully_qualified_class)
586 JniParams.ExtractImportsAndInnerClasses(contents) 586 JniParams.ExtractImportsAndInnerClasses(contents)
587 jni_namespace = ExtractJNINamespace(contents) or options.namespace 587 jni_namespace = ExtractJNINamespace(contents) or options.namespace
588 natives = ExtractNatives(contents, options.ptr_type) 588 natives = ExtractNatives(contents, options.ptr_type)
589 called_by_natives = ExtractCalledByNatives(contents) 589 called_by_natives = ExtractCalledByNatives(contents)
590 if len(natives) == 0 and len(called_by_natives) == 0: 590 if len(natives) == 0 and len(called_by_natives) == 0:
591 raise SyntaxError('Unable to find any JNI methods for %s.' % 591 raise SyntaxError('Unable to find any JNI methods for %s.' %
592 fully_qualified_class) 592 fully_qualified_class)
593 inl_header_file_generator = InlHeaderFileGenerator( 593 inl_header_file_generator = InlHeaderFileGenerator(
594 jni_namespace, fully_qualified_class, natives, called_by_natives, 594 jni_namespace, fully_qualified_class, natives, called_by_natives,
595 [], options) 595 [], options)
596 self.content = inl_header_file_generator.GetContent() 596 self.content = inl_header_file_generator.GetContent()
597 597
598 def _RemoveComments(self, contents, options): 598 # Match single line comments, multiline comments, character literals, and
599 # double-quoted strings.
600 _comment_remover_regex = re.compile(
bulach 2014/04/14 11:30:44 nit: maybe move this before __init__ ? it took me
Torne 2014/04/14 11:41:06 Done.
601 r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
602 re.DOTALL | re.MULTILINE)
603
604 def _RemoveComments(self, contents):
bulach 2014/04/14 11:30:44 ...and then perhaps make this @staticmethod?
Torne 2014/04/14 11:41:06 Static methods can't access members of the class,
599 # We need to support both inline and block comments, and we need to handle 605 # We need to support both inline and block comments, and we need to handle
600 # strings that contain '//' or '/*'. Rather than trying to do all that with 606 # strings that contain '//' or '/*'.
601 # regexps, we just pipe the contents through the C preprocessor. We tell cpp 607 # TODO(bulach): This is a bit hacky. It would be cleaner to use a real Java
602 # the file has already been preprocessed, so it just removes comments and
603 # doesn't try to parse #include, #pragma etc.
604 #
605 # TODO(husky): This is a bit hacky. It would be cleaner to use a real Java
606 # parser. Maybe we could ditch JNIFromJavaSource and just always use 608 # parser. Maybe we could ditch JNIFromJavaSource and just always use
607 # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT. 609 # JNIFromJavaP; or maybe we could rewrite this script in Java and use APT.
608 # http://code.google.com/p/chromium/issues/detail?id=138941 610 # http://code.google.com/p/chromium/issues/detail?id=138941
609 p = subprocess.Popen(args=[options.cpp, '-fpreprocessed'], 611 def replacer(match):
610 stdin=subprocess.PIPE, 612 # Replace matches that are comments with nothing; return literals/strings
611 stdout=subprocess.PIPE, 613 # unchanged.
612 stderr=subprocess.PIPE) 614 s = match.group(0)
613 stdout, _ = p.communicate(contents) 615 if s.startswith('/'):
614 return stdout 616 return ""
bulach 2014/04/14 11:30:44 nit: s/""/''/
Torne 2014/04/14 11:41:06 Done.
617 else:
618 return s
619 return self._comment_remover_regex.sub(replacer, contents)
615 620
616 def GetContent(self): 621 def GetContent(self):
617 return self.content 622 return self.content
618 623
619 @staticmethod 624 @staticmethod
620 def CreateFromFile(java_file_name, options): 625 def CreateFromFile(java_file_name, options):
621 contents = file(java_file_name).read() 626 contents = file(java_file_name).read()
622 fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name, 627 fully_qualified_class = ExtractFullyQualifiedJavaClassName(java_file_name,
623 contents) 628 contents)
624 return JNIFromJavaSource(contents, fully_qualified_class, options) 629 return JNIFromJavaSource(contents, fully_qualified_class, options)
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 root_name = os.path.splitext(os.path.basename(input_file))[0] 1342 root_name = os.path.splitext(os.path.basename(input_file))[0]
1338 output_file = os.path.join(options.output_dir, root_name) + '_jni.h' 1343 output_file = os.path.join(options.output_dir, root_name) + '_jni.h'
1339 if options.jarjar: 1344 if options.jarjar:
1340 with open(options.jarjar) as f: 1345 with open(options.jarjar) as f:
1341 JniParams.SetJarJarMappings(f.read()) 1346 JniParams.SetJarJarMappings(f.read())
1342 GenerateJNIHeader(input_file, output_file, options) 1347 GenerateJNIHeader(input_file, output_file, options)
1343 1348
1344 1349
1345 if __name__ == '__main__': 1350 if __name__ == '__main__':
1346 sys.exit(main(sys.argv)) 1351 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698