Skip to content

Commit 0618ada

Browse files
committed
[Truffle] More work on keyword arguments.
1 parent ca99b12 commit 0618ada

File tree

6 files changed

+33
-19
lines changed

6 files changed

+33
-19
lines changed

core/src/main/java/org/jruby/truffle/nodes/methods/arguments/CheckArityNode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public void executeVoid(VirtualFrame frame) {
4141

4242
private boolean checkArity(int given) {
4343
if (arity.hasKeywords()) {
44-
given -= 1;
44+
// TODO(CS): TODO
45+
return true;
4546
}
4647

4748
if (arity.getRequired() != 0 && given < arity.getRequired()) {

core/src/main/java/org/jruby/truffle/nodes/methods/arguments/ReadKeywordArgumentNode.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424

2525
public class ReadKeywordArgumentNode extends RubyNode {
2626

27+
private final int minimum;
2728
private final String name;
2829
@Child protected RubyNode defaultValue;
2930

30-
public ReadKeywordArgumentNode(RubyContext context, SourceSection sourceSection, String name, RubyNode defaultValue) {
31+
public ReadKeywordArgumentNode(RubyContext context, SourceSection sourceSection, int minimum, String name, RubyNode defaultValue) {
3132
super(context, sourceSection);
33+
this.minimum = minimum;
3234
this.name = name;
3335
this.defaultValue = defaultValue;
3436
}
@@ -37,20 +39,12 @@ public ReadKeywordArgumentNode(RubyContext context, SourceSection sourceSection,
3739
public Object execute(VirtualFrame frame) {
3840
notDesignedForCompilation();
3941

40-
final int last = RubyArguments.getUserArgumentsCount(frame.getArguments()) - 1;
42+
final RubyHash hash = getKeywordsHash(frame);
4143

42-
if (last == -1) {
44+
if (hash == null) {
4345
return defaultValue.execute(frame);
4446
}
4547

46-
final Object hashValue = RubyArguments.getUserArgument(frame.getArguments(), last);
47-
48-
if (!(hashValue instanceof RubyHash)) {
49-
return defaultValue.execute(frame);
50-
}
51-
52-
final RubyHash hash = (RubyHash) hashValue;
53-
5448
Object value = null;
5549

5650
for (Map.Entry<Object, Object> entry : hash.slowToMap().entrySet()) {
@@ -67,4 +61,18 @@ public Object execute(VirtualFrame frame) {
6761
return value;
6862
}
6963

64+
private RubyHash getKeywordsHash(VirtualFrame frame) {
65+
if (RubyArguments.getUserArgumentsCount(frame.getArguments()) <= minimum) {
66+
return null;
67+
}
68+
69+
final Object lastArgument = RubyArguments.getUserArgument(frame.getArguments(), RubyArguments.getUserArgumentsCount(frame.getArguments()) - 1);
70+
71+
if (lastArgument instanceof RubyHash) {
72+
return (RubyHash) lastArgument;
73+
}
74+
75+
return null;
76+
}
77+
7078
}

core/src/main/java/org/jruby/truffle/translator/LoadArgumentsTranslator.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ private enum State {
4040
POST
4141
}
4242

43+
private int required;
4344
private int index;
4445
private State state;
4546

@@ -65,6 +66,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
6566
for (org.jruby.ast.Node arg : node.getPre().childNodes()) {
6667
sequence.add(arg.accept(this));
6768
++index;
69+
required++;
6870
}
6971
}
7072

@@ -89,6 +91,7 @@ public RubyNode visitArgsNode(org.jruby.ast.ArgsNode node) {
8991
for (org.jruby.ast.Node arg : node.getPost().childNodes()) {
9092
sequence.add(arg.accept(this));
9193
++index;
94+
required++;
9295
}
9396
}
9497

@@ -136,7 +139,7 @@ public RubyNode visitKeywordArgNode(org.jruby.ast.KeywordArgNode node) {
136139
throw new UnsupportedOperationException();
137140
}
138141

139-
final RubyNode readNode = new ReadKeywordArgumentNode(context, sourceSection, name, defaultValue);
142+
final RubyNode readNode = new ReadKeywordArgumentNode(context, sourceSection, required, name, defaultValue);
140143
final FrameSlot slot = methodBodyTranslator.getEnvironment().getFrameDescriptor().findFrameSlot(name);
141144

142145
return WriteLocalVariableNodeFactory.create(context, sourceSection, slot, readNode);
@@ -224,7 +227,14 @@ private RubyNode translateLocalAssignment(ISourcePosition sourcePosition, String
224227
} else {
225228
// Optional argument
226229
final RubyNode defaultValue = valueNode.accept(this);
227-
readNode = new ReadOptionalArgumentNode(context, sourceSection, index, index + 1 + argsNode.getPostCount(), defaultValue);
230+
231+
int minimum = index + 1 + argsNode.getPostCount();
232+
233+
if (argsNode.hasKwargs()) {
234+
minimum += 1;
235+
}
236+
237+
readNode = new ReadOptionalArgumentNode(context, sourceSection, index, minimum, defaultValue);
228238
}
229239

230240
final FrameSlot slot = methodBodyTranslator.getEnvironment().getFrameDescriptor().findFrameSlot(name);

spec/truffle/tags/language/method_tags.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ fails:"A method assigns local variables from method parameters for definition \n
3232
fails:"A method assigns local variables from method parameters for definition \n def m(a, (b, (c, *d), *e))\n [a, b, c, d, e]\n end"
3333
fails:"A method assigns local variables from method parameters for definition \n def m(a, (b, (c, *d, (e, (*f)), g), (h, (i, j))))\n [a, b, c, d, e, f, g, h, i, j]\n end"
3434
fails:"A method assigns local variables from method parameters for definition \n def m(a, b:) [a, b] end"
35-
fails:"A method assigns local variables from method parameters for definition \n def m(a, b: 1) [a, b] end"
36-
fails:"A method assigns local variables from method parameters for definition \n def m(a, **) a end"
3735
fails:"A method assigns local variables from method parameters for definition \n def m(a, **k) [a, k] end"
3836
fails:"A method assigns local variables from method parameters for definition \n def m(a=1, (b, (c, *d))) [a, b, c, d] end"
3937
fails:"A method assigns local variables from method parameters for definition \n def m(a=1, (b, (c, *d), *e)) [a, b, c, d, e] end"

spec/truffle/tags/language/predefined_tags.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,3 @@ fails:Predefined global $-0 does not call #to_str to convert the object to a Str
4848
fails:Predefined global $-0 raises a TypeError if assigned a Fixnum
4949
fails:Predefined global $-0 raises a TypeError if assigned a boolean
5050
fails:Global variable $0 raises a TypeError when not given an object that can be coerced to a String
51-
fails:Predefined global $~ is set at the method-scoped level rather than block-scoped

spec/truffle/tags/language/versions/def_2.0_tags.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
fails:An instance method with keyword arguments treats a sole hash argument correctly
2-
fails:An instance method with keyword arguments correctly distinguishes between optional and keyword arguments
31
fails:An instance method with keyword arguments correctly distinguishes between rest and keyword arguments
42
fails:An instance method with keyword arguments should allow keyword rest arguments
53
fails:An instance method with keyword arguments when there is a single keyword argument raises an argument error when a non-keyword argument is provided

0 commit comments

Comments
 (0)