module Inline
require 'java'
class Java
import javax.tools.ToolProvider
import javax.tools.SimpleJavaFileObject
compiler = ToolProvider.system_java_compiler
file_mgr = compiler.get_standard_file_manager(nil, nil, nil)
File.open("#{Inline.directory}/SourceString.java", "w") do |file|
file.write <<EOF
import javax.tools.*;
import java.net.URI;
public class SourceString extends SimpleJavaFileObject {
final String code;
public SourceString(String name, String code) {
super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension),
Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
EOF
end
units = file_mgr.get_java_file_objects_from_strings(["#{Inline.directory}/SourceString.java"])
compiler.get_task(nil, file_mgr, nil, nil, nil, units).call
$CLASSPATH << Dir.pwd
SourceString = ::Java::SourceString
file_mgr.close
def initialize(mod)
@compiler = ToolProvider.system_java_compiler
@file_mgr = @compiler.get_standard_file_manager(nil, nil, nil)
@context = mod
@src = ""
@imports = []
@sigs = []
end
def import(cls)
@imports << cls
end
def load_cache
false
end
def java(src)
@src << src << "\n"
signature = @src.match(/public static\W+(\w+)\W+([a-zA-Z0-9_]+)\((.*)\)/)
@sigs << [signature[1], signature[2], signature[3]]
end
def build
@name = "Java#{@src.hash.abs}"
imports = "import " + @imports.join(";\nimport ") + ";" if @imports.size > 0
full_src = "
#{imports}
public class #{@name} {
#{@src}
}
"
string_src = SourceString.new(@name, full_src)
@compiler.get_task(nil, @file_mgr, nil, nil, nil, [string_src]).call
end
def load
@sigs.each do |sig|
@context.module_eval "const_set :#{@name}, ::Java.const_get(:#{@name}); puts '#{sig[1]}'; def #{sig[1]}(*args); #{@name}.#{sig[1]}(*args); end"
end
end
end
end