PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/Source/JavaScriptCore/Scripts/generate-js-builtins.py

https://gitlab.com/paretje/qtwebkit
Python | 161 lines | 127 code | 7 blank | 27 comment | 8 complexity | b0134a4b63af6defb738b1618d4c9011 MD5 | raw file
  1. #!/usr/bin/env python
  2. #
  3. # Copyright (c) 2014, 2015 Apple Inc. All rights reserved.
  4. # Copyright (c) 2014 University of Washington. All rights reserved.
  5. #
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions
  8. # are met:
  9. # 1. Redistributions of source code must retain the above copyright
  10. # notice, this list of conditions and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. #
  15. # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  16. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  17. # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  18. # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  19. # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  25. # THE POSSIBILITY OF SUCH DAMAGE.
  26. # This script generates C++ bindings for JavaScript builtins.
  27. # Generators for individual files are located in the builtins/ directory.
  28. import fnmatch
  29. import logging
  30. import optparse
  31. import os
  32. logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.ERROR)
  33. log = logging.getLogger('global')
  34. from lazywriter import LazyFileWriter
  35. import builtins
  36. from builtins import *
  37. def generate_bindings_for_builtins_files(builtins_files=[],
  38. output_path=None,
  39. concatenate_output=False,
  40. combined_output=False,
  41. framework_name="",
  42. force_output=False):
  43. generators = []
  44. model = BuiltinsCollection(framework_name=framework_name)
  45. for filepath in builtins_files:
  46. with open(filepath, "r") as file:
  47. file_text = file.read()
  48. file_name = os.path.basename(filepath)
  49. # If this is a test file, then rewrite the filename to remove the
  50. # test running options encoded into the filename.
  51. if file_name.startswith(framework_name):
  52. (_, object_name, _) = file_name.split('-')
  53. file_name = object_name + '.js'
  54. model.parse_builtins_file(file_name, file_text)
  55. if combined_output:
  56. log.debug("Using generator style: combined files for all builtins.")
  57. generators.append(BuiltinsCombinedHeaderGenerator(model))
  58. generators.append(BuiltinsCombinedImplementationGenerator(model))
  59. else:
  60. log.debug("Using generator style: single files for each builtin.")
  61. for object in model.objects:
  62. generators.append(BuiltinsSeparateHeaderGenerator(model, object))
  63. generators.append(BuiltinsSeparateImplementationGenerator(model, object))
  64. log.debug("")
  65. log.debug("Generating bindings for builtins.")
  66. test_result_file_contents = []
  67. for generator in generators:
  68. output_filepath = os.path.join(output_path, generator.output_filename())
  69. log.debug("Generating output file: %s" % generator.output_filename())
  70. output = generator.generate_output()
  71. log.debug("---")
  72. log.debug("\n" + output)
  73. log.debug("---")
  74. if concatenate_output:
  75. test_result_file_contents.append('### Begin File: %s' % generator.output_filename())
  76. test_result_file_contents.append(output)
  77. test_result_file_contents.append('### End File: %s' % generator.output_filename())
  78. test_result_file_contents.append('')
  79. else:
  80. log.debug("Writing file: %s" % output_filepath)
  81. output_file = LazyFileWriter(output_filepath, force_output)
  82. output_file.write(output)
  83. output_file.close()
  84. if concatenate_output:
  85. filename = os.path.join(os.path.basename(builtins_files[0]) + '-result')
  86. output_filepath = os.path.join(output_path, filename)
  87. log.debug("Writing file: %s" % output_filepath)
  88. output_file = LazyFileWriter(output_filepath, force_output)
  89. output_file.write('\n'.join(test_result_file_contents))
  90. output_file.close()
  91. if __name__ == '__main__':
  92. allowed_framework_names = ['JavaScriptCore', 'WebCore']
  93. cli_parser = optparse.OptionParser(usage="usage: %prog [options] Builtin1.js [, Builtin2.js, ...]")
  94. cli_parser.add_option("-i", "--input-directory", help="If specified, generates builtins from all JavaScript files in the specified directory in addition to specific files passed as arguments.")
  95. cli_parser.add_option("-o", "--output-directory", help="Directory where generated files should be written.")
  96. cli_parser.add_option("--framework", type="choice", choices=allowed_framework_names, help="Destination framework for generated files.")
  97. cli_parser.add_option("--force", action="store_true", help="Force output of generated scripts, even if nothing changed.")
  98. cli_parser.add_option("--combined", action="store_true", help="Produce one .h/.cpp file instead of producing one per builtin object.")
  99. cli_parser.add_option("-v", "--debug", action="store_true", help="Log extra output for debugging the generator itself.")
  100. cli_parser.add_option("-t", "--test", action="store_true", help="Enable test mode.")
  101. arg_options, arg_values = cli_parser.parse_args()
  102. if len(arg_values) is 0 and not arg_options.input_directory:
  103. raise ParseException("At least one input file or directory expected.")
  104. if not arg_options.output_directory:
  105. raise ParseException("Missing output directory.")
  106. if arg_options.debug:
  107. log.setLevel(logging.DEBUG)
  108. input_filepaths = arg_values[:]
  109. if arg_options.input_directory:
  110. for filepath in os.listdir(arg_options.input_directory):
  111. input_filepaths.append(os.path.join(arg_options.input_directory, filepath))
  112. input_filepaths = filter(lambda name: fnmatch.fnmatch(name, '*.js'), input_filepaths)
  113. options = {
  114. 'output_path': arg_options.output_directory,
  115. 'framework_name': arg_options.framework,
  116. 'combined_output': arg_options.combined,
  117. 'force_output': arg_options.force,
  118. 'concatenate_output': arg_options.test,
  119. }
  120. log.debug("Generating code for builtins.")
  121. log.debug("Parsed options:")
  122. for option, value in options.items():
  123. log.debug(" %s: %s" % (option, value))
  124. log.debug("")
  125. log.debug("Input files:")
  126. for filepath in input_filepaths:
  127. log.debug(" %s" % filepath)
  128. log.debug("")
  129. try:
  130. generate_bindings_for_builtins_files(builtins_files=input_filepaths, **options)
  131. except ParseException as e:
  132. if arg_options.test:
  133. log.error(e.message)
  134. else:
  135. raise # Force the build to fail.