49
49
import org .truffleruby .language .RubyRootNode ;
50
50
import org .truffleruby .language .RubyTopLevelRootNode ;
51
51
import org .truffleruby .language .SourceIndexLength ;
52
+ import org .truffleruby .language .arguments .ArgumentsDescriptor ;
52
53
import org .truffleruby .language .arguments .EmptyArgumentsDescriptor ;
53
54
import org .truffleruby .language .arguments .ProfileArgumentNodeGen ;
54
55
import org .truffleruby .language .arguments .ReadSelfNode ;
@@ -249,10 +250,12 @@ public RubyNode visitArrayPatternNode(Nodes.ArrayPatternNode node) {
249
250
return defaultVisit (node );
250
251
}
251
252
253
+ // handled in #visitHashNode
252
254
public RubyNode visitAssocNode (Nodes .AssocNode node ) {
253
255
return defaultVisit (node );
254
256
}
255
257
258
+ // handled in #visitHashNode
256
259
public RubyNode visitAssocSplatNode (Nodes .AssocSplatNode node ) {
257
260
return defaultVisit (node );
258
261
}
@@ -446,6 +449,7 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
446
449
}
447
450
448
451
var translatedArguments = translate (arguments );
452
+ var argumentsDescriptor = getKeywordArgumentsDescriptor (arguments );
449
453
450
454
// If the receiver is explicit or implicit 'self' then we can call private methods
451
455
final boolean ignoreVisibility = node .receiver == null || node .receiver instanceof Nodes .SelfNode ;
@@ -493,7 +497,7 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
493
497
receiver ,
494
498
methodName ,
495
499
null ,
496
- EmptyArgumentsDescriptor . INSTANCE ,
500
+ argumentsDescriptor ,
497
501
translatedArguments ,
498
502
false ,
499
503
ignoreVisibility ,
@@ -506,6 +510,35 @@ public RubyNode visitCallNode(Nodes.CallNode node) {
506
510
return rubyNode ;
507
511
}
508
512
513
+ private ArgumentsDescriptor getKeywordArgumentsDescriptor (Nodes .Node [] arguments ) {
514
+ if (arguments .length == 0 ) {
515
+ return EmptyArgumentsDescriptor .INSTANCE ;
516
+ }
517
+
518
+ Nodes .Node last = arguments [arguments .length - 1 ];
519
+
520
+ if (!(last instanceof Nodes .KeywordHashNode )) {
521
+ return EmptyArgumentsDescriptor .INSTANCE ;
522
+ }
523
+
524
+ var keywords = (Nodes .KeywordHashNode ) last ;
525
+
526
+ final List <String > names = new ArrayList <>();
527
+
528
+ for (var n : keywords .elements ) {
529
+ // TODO: we ignore InterpolatedSymbolNode and other arbitrary possible key types here
530
+ // not sure whether we need keys at all
531
+ if (n instanceof Nodes .AssocNode assoc && assoc .key instanceof Nodes .SymbolNode symbol ) {
532
+ names .add (toString (symbol .unescaped ));
533
+ }
534
+ }
535
+
536
+ var array = names .toArray (StringUtils .EMPTY_STRING_ARRAY );
537
+ var manager = language .keywordArgumentsDescriptorManager ;
538
+ var descriptor = manager .getArgumentsDescriptor (array );
539
+ return descriptor ;
540
+ }
541
+
509
542
public RubyNode visitCallOperatorWriteNode (Nodes .CallOperatorWriteNode node ) {
510
543
return defaultVisit (node );
511
544
}
@@ -1287,7 +1320,9 @@ public RubyNode visitInterpolatedXStringNode(Nodes.InterpolatedXStringNode node)
1287
1320
}
1288
1321
1289
1322
public RubyNode visitKeywordHashNode (Nodes .KeywordHashNode node ) {
1290
- return defaultVisit (node );
1323
+ // store keyword arguments as a literal Hash
1324
+ final var hash = new Nodes .HashNode (node .elements , node .startOffset , node .length );
1325
+ return hash .accept (this );
1291
1326
}
1292
1327
1293
1328
public RubyNode visitLambdaNode (Nodes .LambdaNode node ) {
@@ -2154,6 +2189,11 @@ protected String toString(Nodes.Node node) {
2154
2189
node .length , sourceEncoding .tencoding , false ), sourceEncoding );
2155
2190
}
2156
2191
2192
+ protected String toString (byte [] bytes ) {
2193
+ return TStringUtils .toJavaStringOrThrow (TruffleString .fromByteArrayUncached (bytes , 0 ,
2194
+ bytes .length , sourceEncoding .tencoding , false ), sourceEncoding );
2195
+ }
2196
+
2157
2197
protected SourceSection getSourceSection (Nodes .Node yarpNode ) {
2158
2198
return source .createSection (yarpNode .startOffset , yarpNode .length );
2159
2199
}
0 commit comments