Skip to content

Commit

Permalink
Fix for JRUBY-1076 (provide access to methods on blank-slated Java pa…
Browse files Browse the repository at this point in the history
…ckage modules). Implemented on trunk long ago.

git-svn-id: http://svn.codehaus.org/jruby/branches/jruby-1_0@5890 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information
bdortch committed Feb 10, 2008
1 parent 4a5c792 commit 9cb9b6c
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 35 deletions.
15 changes: 15 additions & 0 deletions lib/ruby/site_ruby/1.8/builtin/javasupport/core_ext/kernel.rb
@@ -1,3 +1,18 @@
# Prevent methods added to Kernel from being added to the
# blank-slate JavaPackageModuleTemplate
module Kernel
class << self
alias_method :java_package_method_added, :method_added

def method_added(name)
result = java_package_method_added(name)
JavaPackageModuleTemplate.__block__(name) if self == Kernel
result
end
private :method_added
end
end

# Create convenience methods for top-level java packages so we do not need to prefix
# with 'Java::'. We undef these methods within Package in case we run into 'com.foo.com'.
[:java, :javax, :com, :org].each do |meth|
Expand Down
13 changes: 13 additions & 0 deletions lib/ruby/site_ruby/1.8/builtin/javasupport/core_ext/object.rb
Expand Up @@ -2,6 +2,19 @@ class ConstantAlreadyExistsError < RuntimeError
end

class Object
# Prevent methods added to Object from being added to the
# blank-slate JavaPackageModuleTemplate
class << self
alias_method :java_package_method_added, :method_added

def method_added(name)
result = java_package_method_added(name)
JavaPackageModuleTemplate.__block__(name) if self == Object
result
end
private :method_added
end

# include the class specified by +include_class+ into the current namespace,
# using either its base name or by using a name returned from an optional block,
# passing all specified classes in turn and providing the block package name
Expand Down
18 changes: 18 additions & 0 deletions lib/ruby/site_ruby/1.8/builtin/javasupport/java.rb
Expand Up @@ -24,8 +24,26 @@ def method_missing(sym, *args)

# :nodoc:
module JavaPackageModuleTemplate
@@keep = /^(__|<|>|=)|^(class|const_missing|inspect|method_missing|to_s)$|(\?|!|=)$/
class << self

# blank-slate logic relocated from org.jruby.javasupport.Java
instance_methods.each do |meth|
unless meth =~ @@keep
# keep aliased methods for those we'll undef, for use by IRB and other utilities
unless method_defined?(method_alias = :"__#{meth}__")
alias_method method_alias, meth
end
undef_method meth
end
end

def __block__(name)
if (name_str = name.to_s) !~ @@keep
(class<<self;self;end).__send__(:undef_method, name) rescue nil
end
end

def const_missing(const)
JavaUtilities.get_proxy_class(@package_name + const.to_s)
end
Expand Down
35 changes: 0 additions & 35 deletions src/org/jruby/javasupport/Java.java
Expand Up @@ -426,26 +426,6 @@ private static RubyModule getJavaPackageModule(Ruby runtime, String packageStrin
}
}

private static final IRubyObject[] EMPTY_ARGS = new IRubyObject[0];

private static final HashSet PACKAGE_MODULE_KEEP_METHODS = new HashSet();
static {
// keeping some methods we must have, and some others that are not strictly
// necessary, but won't collide with any potential package names. note that
// inspect, to_s and respond_to? are needed for console display; otherwise
// exceptions are raised.
final String[] methods = {
"<", "<=", "<=>", "==", "===", ">", ">=", "=~", "__id__", "__send__",
"autoload?", "class", "const_defined?", "const_missing", "eql?",
"equal?", "frozen?", "include?", "inspect", "instance_of?", "is_a?",
"kind_of?", "method_defined?", "method_missing", "nil?", "respond_to?",
"tainted?", "to_s"
};
for (int i = methods.length; --i >= 0; ) {
PACKAGE_MODULE_KEEP_METHODS.add(methods[i]);
}
}

private static RubyModule createPackageModule(RubyModule parent, String name, String packageString) {
Ruby runtime = parent.getRuntime();
RubyModule packageModule = (RubyModule)runtime.getJavaSupport()
Expand All @@ -456,21 +436,6 @@ private static RubyModule createPackageModule(RubyModule parent, String name, St
// this is where we'll get connected when classes are opened using
// package module syntax.
packageModule.addClassProvider(JAVA_PACKAGE_CLASS_PROVIDER);

// undefined methods aren't carried over when the template is dup'ed
// (see JRUBY-948), so we'll undef them here.
// TODO: need to catch later additions to Object/Kernel. yuk. that's a lot
// of processing for method_added et al...
RubyClass singleton = packageModule.getSingletonClass();
Object[] snglMeths = singleton.public_instance_methods(EMPTY_ARGS).toArray();
java.util.Arrays.sort(snglMeths);
for (int i = snglMeths.length; --i >= 0; ) {
String methodName = (String)snglMeths[i];
if (!PACKAGE_MODULE_KEEP_METHODS.contains(methodName)) {
singleton.undef(methodName);
}
}

parent.const_set(runtime.newSymbol(name), packageModule);
return packageModule;
}
Expand Down

0 comments on commit 9cb9b6c

Please sign in to comment.