Skip to content

Commit

Permalink
[Truffle] Implemented 2-arg version of File.basename.
Browse files Browse the repository at this point in the history
  • Loading branch information
nirvdrum committed Feb 3, 2015
1 parent c95a0ec commit 4614c64
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
7 changes: 0 additions & 7 deletions spec/truffle/tags/core/file/basename_tags.txt
@@ -1,13 +1,6 @@
fails:File.basename returns the basename of a path (basic cases)
fails:File.basename returns the last component of the filename
fails:File.basename returns an string
fails:File.basename returns the basename for unix format
fails:File.basename returns the basename for edge cases
fails:File.basename ignores a trailing directory separator
fails:File.basename returns the basename for unix suffix
fails:File.basename raises a TypeError if the arguments are not String types
fails:File.basename accepts an object that has a #to_path method
fails:File.basename raises an ArgumentError if passed more than two arguments
fails:File.basename returns the extension for a multibyte filename
fails(windows):File.basename returns the basename for windows
fails(windows):File.basename returns basename windows unc
Expand Down
22 changes: 20 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/FileNodes.java
Expand Up @@ -52,7 +52,7 @@ public RubyString absolutePath(RubyString path) {

}

@CoreMethod(names = "basename", onSingleton = true, required = 1)
@CoreMethod(names = "basename", onSingleton = true, required = 1, optional = 1)
public abstract static class BasenameNode extends CoreMethodNode {

public BasenameNode(RubyContext context, SourceSection sourceSection) {
Expand All @@ -64,12 +64,30 @@ public BasenameNode(BasenameNode prev) {
}

@Specialization
public RubyString basename(RubyString path) {
public RubyString basename(RubyString path, @SuppressWarnings("unused") UndefinedPlaceholder extension) {
notDesignedForCompilation();

return getContext().makeString(new File(path.toString()).getName());
}

@Specialization
public RubyString basename(RubyString path, RubyString extension) {
notDesignedForCompilation();

final String extensionAsString = extension.toString();
final String name = new File(path.toString()).getName();
final String basename;

if (extensionAsString.equals(".*") && name.indexOf('.') != -1) {
basename = name.substring(0, name.lastIndexOf('.'));
} else if (name.endsWith(extensionAsString)) {
basename = name.substring(0, name.lastIndexOf(extensionAsString));
} else {
basename = name;
}

return getContext().makeString(basename);
}
}

@CoreMethod(names = "close")
Expand Down

2 comments on commit 4614c64

@eregon
Copy link
Member

@eregon eregon commented on 4614c64 Feb 3, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought to use Rubinius for this but it seems fairly complex and rather obscure compared to this clear implementation.

@nirvdrum
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not wild about converting to Java Strings here. Doing it in Ruby might be faster, but this was much simpler for sure.

Please sign in to comment.