Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SyntaxError#path #3433

Merged
1 commit merged into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spec/ruby/core/exception/fixtures/syntax_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1+1=2
26 changes: 26 additions & 0 deletions spec/ruby/core/exception/syntax_error_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require_relative '../../spec_helper'


ruby_version_is "3.2" do
describe "SyntaxError#path" do
it "returns the file path provided to eval" do
expected = 'speccing.rb'
-> {
eval('if true', TOPLEVEL_BINDING, expected)
}.should raise_error(SyntaxError) { |e|
e.path.should == expected
}
end

it "returns the file path that raised an exception" do
expected_path = fixture(__FILE__, 'syntax_error.rb')
-> {
require_relative 'fixtures/syntax_error'
}.should raise_error(SyntaxError) {|e| e.path.should == expected_path }
end

it "returns nil when constructed directly" do
SyntaxError.new.path.should == nil
end
end
end
4 changes: 2 additions & 2 deletions spec/ruby/core/kernel/eval_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
it "includes file and line information in syntax error" do
expected = 'speccing.rb'
-> {
eval('if true',TOPLEVEL_BINDING, expected)
eval('if true', TOPLEVEL_BINDING, expected)
}.should raise_error(SyntaxError) { |e|
e.message.should =~ /#{expected}:1:.+/
}
Expand All @@ -144,7 +144,7 @@
it "evaluates string with given filename and negative linenumber" do
expected_file = 'speccing.rb'
-> {
eval('if true',TOPLEVEL_BINDING, expected_file, -100)
eval('if true', TOPLEVEL_BINDING, expected_file, -100)
}.should raise_error(SyntaxError) { |e|
e.message.should =~ /#{expected_file}:-100:.+/
}
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/org/truffleruby/core/exception/SyntaxErrorNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
import org.truffleruby.annotations.CoreMethod;
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
import org.truffleruby.annotations.CoreModule;
import org.truffleruby.core.encoding.Encodings;
import org.truffleruby.core.klass.RubyClass;
import org.truffleruby.annotations.Visibility;
import org.truffleruby.language.objects.AllocationTracing;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.object.Shape;
import com.oracle.truffle.api.source.Source;

@CoreModule(value = "SyntaxError", isClass = true)
public abstract class SyntaxErrorNodes {
Expand All @@ -35,4 +40,27 @@ RubySyntaxError allocateSyntaxError(RubyClass rubyClass) {

}

@CoreMethod(names = "path")
public abstract static class PathNode extends CoreMethodArrayArgumentsNode {

@TruffleBoundary
@Specialization
Object path(RubySyntaxError syntaxError) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is to handle RubyString / Nil - a brief search of the codebase suggested that this was how we handled varying return types, did I miss something?

Copy link
Member

Choose a reason for hiding this comment

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

This is correct. Looks great!

if (!syntaxError.hasSourceLocation()) {
return nil;
}

Source source;
try {
source = syntaxError.getSourceLocation().getSource();
} catch (UnsupportedMessageException e) {
throw CompilerDirectives.shouldNotReachHere(e);
}

var path = getLanguage().getPathToTStringCache().getCachedPath(source);
return createString(path, Encodings.UTF_8);
}

}

}
Loading