PageRenderTime 41ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/jruby-1.5.5/lib/ruby/site_ruby/shared/jruby/compiler.rb

https://github.com/ThoughtWorksStudios/mingle_hg_plugin
Ruby | 200 lines | 158 code | 39 blank | 3 comment | 12 complexity | 6850d98eda7c266c2328313d0dce93f2 MD5 | raw file
Possible License(s): Apache-2.0, GPL-3.0, JSON
  1. require 'optparse'
  2. require 'fileutils'
  3. require 'digest/sha1'
  4. require 'jruby'
  5. require 'jruby/compiler/java_class'
  6. module JRuby::Compiler
  7. BAIS = java.io.ByteArrayInputStream
  8. Mangler = org.jruby.util.JavaNameMangler
  9. BytecodeCompiler = org.jruby.compiler.impl.StandardASMCompiler
  10. ASTCompiler = org.jruby.compiler.ASTCompiler
  11. JavaFile = java.io.File
  12. MethodSignatureNode = org.jruby.ast.java_signature.MethodSignatureNode
  13. DEFAULT_PREFIX = ""
  14. def default_options
  15. {
  16. :basedir => Dir.pwd,
  17. :prefix => DEFAULT_PREFIX,
  18. :target => Dir.pwd,
  19. :java => false,
  20. :javac => false,
  21. :classpath => [],
  22. :javac_options => [],
  23. :sha1 => false,
  24. :handles => false
  25. }
  26. end
  27. module_function :default_options
  28. def compile_argv(argv)
  29. options = default_options
  30. OptionParser.new("", 24, ' ') do |opts|
  31. opts.banner = "jrubyc [options] (FILE|DIRECTORY)"
  32. opts.separator ""
  33. opts.on("-d", "--dir DIR", "Use DIR as the root of the compiled package and filename") do |dir|
  34. options[:basedir] = dir
  35. end
  36. opts.on("-p", "--prefix PREFIX", "Prepend PREFIX to the file path and package. Default is no prefix.") do |pre|
  37. options[:prefix] = pre
  38. end
  39. opts.on("-t", "--target TARGET", "Output files to TARGET directory") do |tgt|
  40. options[:target] = tgt
  41. end
  42. opts.on("-J OPTION", "Pass OPTION to javac for javac compiles") do |tgt|
  43. options[:javac_options] << tgt
  44. end
  45. opts.on("--java", "Generate .java classes to accompany the script") do
  46. options[:java] = true
  47. end
  48. opts.on("--javac", "Generate and compile .java classes to accompany the script") do
  49. options[:javac] = true
  50. end
  51. opts.on("-c", "--classpath CLASSPATH", "Add a jar to the classpath for building") do |cp|
  52. options[:classpath].concat cp.split(':')
  53. end
  54. opts.on("--sha1", "Compile to a class named using the SHA1 hash of the source file") do
  55. options[:sha1] = true
  56. end
  57. opts.on("--handles", "Also generate all direct handle classes for the source file") do
  58. options[:handles] = true
  59. end
  60. opts.parse!(argv)
  61. end
  62. if (argv.length == 0)
  63. raise "No files or directories specified"
  64. end
  65. compile_files_with_options(argv, options)
  66. end
  67. module_function :compile_argv
  68. # deprecated, but retained for backward compatibility
  69. def compile_files(filenames, basedir = Dir.pwd, prefix = DEFAULT_PREFIX, target = Dir.pwd, java = false, javac = false, javac_options = [], classpath = [])
  70. compile_files_with_options(
  71. filenames,
  72. :basedir => basedir,
  73. :prefix => prefix,
  74. :target => target,
  75. :java => java,
  76. :javac => javac,
  77. :javac_options => javac_options,
  78. :classpath => classpath,
  79. :sha1 => false,
  80. :handles => false
  81. )
  82. end
  83. module_function :compile_files
  84. def compile_files_with_options(filenames, options = default_options)
  85. runtime = JRuby.runtime
  86. unless File.exist? options[:target]
  87. raise "Target dir not found: #{options[:target]}"
  88. end
  89. files = []
  90. # The compilation code
  91. compile_proc = proc do |filename|
  92. begin
  93. file = File.open(filename)
  94. if options[:sha1]
  95. pathname = "ruby.jit.FILE_" + Digest::SHA1.hexdigest(File.read(filename)).upcase
  96. else
  97. pathname = Mangler.mangle_filename_for_classpath(filename, options[:basedir], options[:prefix])
  98. end
  99. inspector = org.jruby.compiler.ASTInspector.new
  100. source = file.read
  101. node = runtime.parse_file(BAIS.new(source.to_java_bytes), filename, nil)
  102. if options[:java] || options[:javac]
  103. ruby_script = JavaGenerator.generate_java(node, filename)
  104. ruby_script.classes.each do |cls|
  105. java_dir = File.join(options[:target], cls.package.gsub('.', '/'))
  106. FileUtils.mkdir_p java_dir
  107. java_src = File.join(java_dir, cls.name + ".java")
  108. puts "Generating Java class #{cls.name} to #{java_src}"
  109. files << java_src
  110. File.open(java_src, 'w') do |f|
  111. f.write(cls.to_s)
  112. end
  113. end
  114. else
  115. puts "Compiling #{filename} to class #{pathname}"
  116. inspector.inspect(node)
  117. asmCompiler = BytecodeCompiler.new(pathname.gsub(".", "/"), filename)
  118. compiler = ASTCompiler.new
  119. compiler.compile_root(node, asmCompiler, inspector)
  120. target_file = JavaFile.new(options[:target])
  121. asmCompiler.write_class(target_file)
  122. if options[:handles]
  123. puts "Generating direct handles for #{filename}"
  124. asmCompiler.write_invokers(target_file)
  125. end
  126. end
  127. 0
  128. rescue Exception
  129. puts "Failure during compilation of file #{filename}:\n#{$!}"
  130. puts $!.backtrace
  131. 1
  132. ensure
  133. file.close unless file.nil?
  134. end
  135. end
  136. errors = 0
  137. # Process all the file arguments
  138. Dir[*filenames].each do |filename|
  139. unless File.exists? filename
  140. puts "Error -- file not found: #{filename}"
  141. errors += 1
  142. next
  143. end
  144. if (File.directory?(filename))
  145. puts "Compiling all in '#{File.expand_path(filename)}'..."
  146. Dir.glob(filename + "/**/*.rb").each { |filename|
  147. errors += compile_proc[filename]
  148. }
  149. else
  150. errors += compile_proc[filename]
  151. end
  152. end
  153. if options[:javac]
  154. javac_string = JavaGenerator.generate_javac(files, options)
  155. puts javac_string
  156. system javac_string
  157. end
  158. errors
  159. end
  160. module_function :compile_files_with_options
  161. end