Permalink
Browse files

First round of fixes to get jrubyc (AOT compiler) working correctly, …

…as beta 1 behavior.

git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@5932 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information...
1 parent 303f6b7 commit bc97a22f13b8fd026554c7f9df0b137c443c4cfc @headius headius committed Feb 14, 2008
View
@@ -2,4 +2,32 @@
require 'jruby/jrubyc'
-JRubyCompiler::compile_args
+basedir = Dir.pwd
+prefix = "ruby"
+target = Dir.pwd
+
+opt_parser = OptionParser.new("", 24, ' ') do |opts|
+ opts.banner = "jrubyc [options] (FILE|DIRECTORY)"
+ opts.separator ""
+
+ opts.on("-d", "--dir DIR", "Use DIR as the root of the compiled package and filename") do |dir|
+ basedir = dir
+ end
+
+ opts.on("-p", "--prefix PREFIX", "Prepend PREFIX to the file path and package. \"ruby\" is default") do |pre|
+ prefix = pre
+ end
+
+ opts.on("-t", "--target TARGET", "Output files to TARGET directory") do |tgt|
+ target = tgt
+ end
+
+ opts.parse!(ARGV)
+end
+
+if (ARGV.length == 0)
+ puts "No files or directories specified"
+ exit 1
+end
+
+JRubyCompiler::compile_files(ARGV, basedir, prefix, target)
@@ -1,3 +1,4 @@
+require 'optparse'
require 'jruby'
module JRubyCompiler
@@ -8,22 +9,21 @@ module JRubyCompiler
JavaFile = java.io.File
module_function
- def compile_args
+ def compile_files(filenames, basedir = Dir.pwd, prefix = "ruby", target = Dir.pwd)
runtime = JRuby.runtime
-
- if ARGV.size < 1
- puts "Usage: jrubyc <filename.rb> [<filename.rb> ...]"
- exit
+
+ unless File.exist? target
+ puts "Target dir not found: #{target}"
+ exit 1
end
# The compilation code
compile_proc = proc do |filename|
begin
file = File.open(filename)
- destdir = Dir.pwd
- classpath = Mangler.mangle_filename_for_classpath(filename)
- puts " Compiling #{filename} to class #{classpath}"
+ classpath = Mangler.mangle_filename_for_classpath(filename, basedir, prefix)
+ puts "Compiling #{filename} to class #{classpath}"
inspector = org.jruby.compiler.ASTInspector.new
@@ -36,7 +36,7 @@ def compile_args
compiler = ASTCompiler.new
compiler.compile_root(node, asmCompiler, inspector)
- asmCompiler.write_class(JavaFile.new(destdir))
+ asmCompiler.write_class(JavaFile.new(target))
rescue Exception
puts "Failure during compilation of file #{filename}:\n#{$!}"
ensure
@@ -45,7 +45,7 @@ def compile_args
end
# Process all the file arguments
- ARGV.each do |filename|
+ filenames.each do |filename|
unless File.exists? filename
puts "Error -- file not found: #{filename}"
next
@@ -5,6 +5,7 @@
package org.jruby.util;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.regex.Pattern;
@@ -15,7 +16,19 @@
public class JavaNameMangler {
public static final Pattern PATH_SPLIT = Pattern.compile("[/\\\\]");
+ public static String mangledFilenameForStartupClasspath(String filename) {
+ if (filename.equals("-e")) {
+ return "__dash_e__";
+ }
+
+ return mangleFilenameForClasspath(filename, null, "ruby");
+ }
+
public static String mangleFilenameForClasspath(String filename) {
+ return mangleFilenameForClasspath(filename, null, "ruby");
+ }
+
+ public static String mangleFilenameForClasspath(String filename, String parent, String prefix) {
try {
String classPath = "";
if(filename.indexOf("!") != -1) {
@@ -25,20 +38,39 @@ public static String mangleFilenameForClasspath(String filename) {
classPath = new JRubyFile(filename).getCanonicalPath().toString();
}
+ if (parent != null && parent.length() > 0) {
+ String parentPath = new JRubyFile(parent).getCanonicalPath().toString();
+ if (!classPath.startsWith(parentPath)) {
+ throw new FileNotFoundException("File path " + classPath +
+ " does not start with parent path " + parentPath);
+ }
+ int parentLength = parentPath.length();
+ classPath = classPath.substring(parentLength);
+ }
+
String[] pathElements = PATH_SPLIT.split(classPath);
- StringBuffer newPath = new StringBuffer("ruby");
+ StringBuffer newPath = new StringBuffer(prefix);
for (String element : pathElements) {
if (element.length() <= 0) {
continue;
}
- newPath.append("/");
+ if (newPath.length() > 0) {
+ newPath.append("/");
+ }
+
if (!Character.isJavaIdentifierStart(element.charAt(0))) {
newPath.append("$");
}
newPath.append(mangleStringForCleanJavaIdentifier(element));
}
+
+ // strip off "_dot_rb" for .rb files
+ int dotRbIndex = newPath.indexOf("_dot_rb");
+ if (dotRbIndex != -1 && dotRbIndex == newPath.length() - 7) {
+ newPath.delete(dotRbIndex, dotRbIndex + 7);
+ }
return newPath.toString();
} catch (IOException ioe) {
@@ -47,20 +79,13 @@ public static String mangleFilenameForClasspath(String filename) {
}
}
- public static String mangledFilenameForStartupClasspath(String filename) {
- if (filename.equals("-e")) {
- return "__dash_e__";
- }
-
- return mangleFilenameForClasspath(filename);
- }
-
public static String mangleStringForCleanJavaIdentifier(String name) {
char[] characters = name.toCharArray();
StringBuffer cleanBuffer = new StringBuffer();
boolean prevWasReplaced = false;
for (int i = 0; i < characters.length; i++) {
- if (Character.isJavaIdentifierStart(characters[i])) {
+ if ((i == 0 && Character.isJavaIdentifierStart(characters[i]))
+ || Character.isJavaIdentifierPart(characters[i])) {
cleanBuffer.append(characters[i]);
prevWasReplaced = false;
} else {
@@ -89,12 +114,10 @@ public static String mangleStringForCleanJavaIdentifier(String name) {
cleanBuffer.append("aref_");
i++;
} else {
- // can this ever happen?
cleanBuffer.append("lbracket_");
}
continue;
case ']':
- // given [ logic above, can this ever happen?
cleanBuffer.append("rbracket_");
continue;
case '+':
@@ -342,7 +342,7 @@ private boolean shouldRunInProcess(Ruby runtime, String command) {
}
String[] slashDelimitedTokens = command.split("/");
String finalToken = slashDelimitedTokens[slashDelimitedTokens.length - 1];
- return (finalToken.indexOf("ruby") != -1 || finalToken.endsWith(".rb") || finalToken.endsWith("irb"));
+ return (finalToken.indexOf("ruby") == (finalToken.length() - 4) || finalToken.endsWith(".rb") || finalToken.endsWith("irb"));
}
private boolean shouldRunInShell(String shell, String[] args) {
@@ -0,0 +1,59 @@
+require 'test/unit'
+require 'stringio'
+require 'java'
+
+class TestJrubyc < Test::Unit::TestCase
+ def setup
+ @jrubyc_command = File.join(ENV_JAVA['jruby.home'], "bin", "jrubyc")
+ end
+ def test_basic
+ begin
+ output = `#{@jrubyc_command} #{__FILE__}`
+
+ assert_equal(
+ "Compiling #{__FILE__} to class ruby/test/compiler/test_jrubyc\n",
+ output)
+
+ assert(File.exist?("ruby/test/compiler/test_jrubyc.class"))
+ ensure
+ File.delete("ruby") rescue nil
+ end
+ end
+
+ def test_target
+ begin
+ output = `#{@jrubyc_command} -t /tmp #{__FILE__}`
+
+ assert_equal(
+ "Compiling #{__FILE__} to class ruby/test/compiler/test_jrubyc\n",
+ output)
+
+ assert(File.exist?("ruby/test/compiler/test_jrubyc.class"))
+ ensure
+ File.delete("ruby") rescue nil
+ end
+ end
+
+ def test_bad_target
+ output = `#{@jrubyc_command} -t does_not_exist #{__FILE__}`
+
+ assert_equal(
+ "Target dir not found: does_not_exist\n",
+ output)
+ assert_equal(1, $?.exitstatus)
+ end
+
+ def test_prefix
+ begin
+ output = `#{@jrubyc_command} -p foo #{__FILE__}`
+
+ assert_equal(
+ "Compiling #{__FILE__} to class foo/test/compiler/test_jrubyc\n",
+ output)
+
+ assert(File.exist?("foo/test/compiler/test_jrubyc.class"))
+ ensure
+ File.delete("ruby") rescue nil
+ end
+ end
+end
View
@@ -36,6 +36,7 @@ test_java_accessible_object
test_java_big_decimal
test_java_extension
test_jruby_internals
+compiler/test_jrubyc
test_launching_by_shell_script
test_local_jump_error
test_marshal_gemspec

0 comments on commit bc97a22

Please sign in to comment.