Skip to content

Commit 818ee11

Browse files
committed
Make Java.import import a Java class in the enclosing module instead of always as a top-level constant
1 parent 8738a6a commit 818ee11

File tree

6 files changed

+27
-29
lines changed

6 files changed

+27
-29
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Performance:
4545
Changes:
4646

4747
* `foreign_object.class` on foreign objects is no longer special and uses `Kernel#class` (it used to return the `java.lang.Class` object for a Java type or `getMetaObject()`, but that is too incompatible with Ruby code).
48+
* `Java.import name` imports a Java class in the enclosing module instead of always as a top-level constant.
4849

4950
# 21.2.0
5051

doc/user/jruby-migration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ frame.setVisible(true)
354354
```
355355

356356
Instead of using Ruby metaprogramming to simulate a Java package name, we explicitly import classes.
357-
`Java.import` is similar to JRuby's `java_import`, and does `::ClassName = Java.type('package.ClassName')`.
357+
`Java.import` is similar to JRuby's `java_import`, and does `ClassName = Java.type('package.ClassName')`.
358358

359359
Constants are read by reading properties of the class rather than using Ruby notation.
360360

@@ -367,7 +367,7 @@ This is only available in GraalVM - not in the standalone distribution installed
367367

368368
In JRuby, Java classes can either be referenced in the `Java` module, such as `Java::ComFoo::Bar`, or if they have a common TLD they can be referenced as `com.foo.Bar`. `java_import com.foo.Bar` will define `Bar` as a top-level constant.
369369

370-
In TruffleRuby, Java classes are referred to using either `Java.type('com.foo.Bar')`, which you would then normally assign to a constant, or you can use `Java.import 'com.foo.Bar'` to have `Bar` defined as a top-level constant.
370+
In TruffleRuby, Java classes are referred to using either `Java.type('com.foo.Bar')`, which you would then normally assign to a constant, or you can use `Java.import 'com.foo.Bar'` to have `Bar` defined in the enclosing module.
371371

372372
### Wildcard Package Imports
373373

doc/user/polyglot.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ With the type object, `.new` will create an instance, `.foo` will call the stati
132132
To access methods of the `java.lang.Class` instance, use `[:class]`, such as `MyClass[:class].getName`.
133133
You can also go from the `java.lang.Class` instance to the Java type by using `[:static]`.
134134

135-
To import a Java class as a top-level constant, use `Java.import 'name'`.
135+
To import a Java class in the enclosing module, use `MyClass = Java.type 'java.lang.MyClass'` or `Java.import 'java.lang.MyClass'`.
136136

137137
## Embedding in Java
138138

spec/tags/truffle/interop/java_import_tags.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

spec/truffle/interop/java_import_spec.rb

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,37 @@
1010

1111
guard -> { !TruffleRuby.native? } do
1212
describe "Java.import" do
13-
14-
it "imports a class to the top-level" do
15-
ruby_exe(%{
13+
it "imports a class under the enclosing module" do
14+
module TruffleJavaImportSpecs1
1615
Java.import 'java.math.BigInteger'
17-
puts BigInteger.new('1234').toString
18-
}).should == "1234\n"
16+
BigInteger.new('1234').toString.should == "1234"
17+
end
18+
19+
TruffleJavaImportSpecs1.should.const_defined?('BigInteger', false)
20+
Object.should_not.const_defined?('BigInteger')
1921
end
2022

2123
it "returns the imported class" do
22-
ruby_exe(%{
23-
puts Java.import('java.math.BigInteger').class.getName
24-
}).should == "java.math.BigInteger\n"
24+
module TruffleJavaImportSpecs2
25+
Java.import('java.math.BigInteger')[:class].getName.should == "java.math.BigInteger"
26+
end
2527
end
2628

2729
it "can import classes twice" do
28-
ruby_exe(%{
30+
module TruffleJavaImportSpecs3
2931
Java.import 'java.math.BigInteger'
3032
Java.import 'java.math.BigInteger'
31-
puts BigInteger.new('1234').toString
32-
}).should == "1234\n"
33+
BigInteger.new('1234').toString.should == "1234"
34+
end
3335
end
3436

3537
it "raises an error if the constant is already defined" do
36-
ruby_exe(%{
38+
module TruffleJavaImportSpecs4
3739
BigInteger = '14'
38-
begin
40+
-> {
3941
Java.import 'java.math.BigInteger'
40-
rescue NameError => e
41-
puts e
42-
end
43-
}).should == "constant BigInteger already set\n"
42+
}.should raise_error(NameError, "constant BigInteger already set")
43+
end
4444
end
45-
4645
end
4746
end

src/main/ruby/truffleruby/core/truffle/polyglot.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,18 +414,21 @@ def self.type(name)
414414
end
415415

416416
def self.import(name)
417+
nesting = Primitive.caller_nesting
418+
mod = nesting.first || Object
419+
417420
name = name.to_s
418421
simple_name = name.split('.').last
419422
type = Java.type(name)
420-
if Object.const_defined?(simple_name)
421-
current = Object.const_get(simple_name)
423+
if mod.const_defined?(simple_name)
424+
current = mod.const_get(simple_name)
422425
if current.equal?(type)
423426
# Ignore - it's already set
424427
else
425428
raise NameError, "constant #{simple_name} already set"
426429
end
427430
else
428-
Object.const_set simple_name, type
431+
mod.const_set simple_name, type
429432
end
430433
type
431434
end

0 commit comments

Comments
 (0)