2222import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .instanceOf ;
2323import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .lengthGt ;
2424import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .lengthGte ;
25+ import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .returnIf ;
2526import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .singleElement ;
2627import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .stringValue ;
2728import static com .oracle .truffle .r .nodes .builtin .CastBuilder .Predef .toBoolean ;
4243import com .oracle .truffle .r .nodes .attributes .GetFixedAttributeNode ;
4344import com .oracle .truffle .r .nodes .builtin .NodeWithArgumentCasts .Casts ;
4445import com .oracle .truffle .r .nodes .builtin .RExternalBuiltinNode ;
46+ import com .oracle .truffle .r .nodes .builtin .casts .fluent .PreinitialPhaseBuilder ;
4547import com .oracle .truffle .r .nodes .function .ClassHierarchyScalarNode ;
4648import com .oracle .truffle .r .nodes .function .ClassHierarchyScalarNodeGen ;
4749import com .oracle .truffle .r .nodes .function .PromiseHelperNode ;
6769import com .oracle .truffle .r .runtime .data .RNull ;
6870import com .oracle .truffle .r .runtime .data .RPromise ;
6971import com .oracle .truffle .r .runtime .data .RS4Object ;
72+ import com .oracle .truffle .r .runtime .data .RSymbol ;
7073import com .oracle .truffle .r .runtime .data .RTypedValue ;
7174import com .oracle .truffle .r .runtime .data .model .RAbstractStringVector ;
7275import com .oracle .truffle .r .runtime .env .REnvironment ;
8285public class MethodsListDispatch {
8386
8487 private static void checkSingleString (Casts casts , int argNum , String argName , String msg , boolean nonEmpty , Function <Object , String > clsHierFn ,
85- Function <Object , Integer > vecLenFn ) {
88+ Function <Object , Integer > vecLenFn , boolean allowSymbol ) {
89+
90+ PreinitialPhaseBuilder builder = casts .arg (argNum , argName ).defaultError (Message .SINGLE_STRING_WRONG_TYPE , msg , clsHierFn );
91+ if (allowSymbol ) {
92+ builder .returnIf (instanceOf (RSymbol .class ));
93+ }
94+ checkSingleString (builder , msg , nonEmpty , vecLenFn );
95+ }
96+
97+ private static void checkSingleString (PreinitialPhaseBuilder builder , String msg , boolean nonEmpty , Function <Object , Integer > vecLenFn ) {
8698 //@formatter:off
87- casts .arg (argNum , argName ).
88- defaultError (RError .Message .SINGLE_STRING_WRONG_TYPE , msg , clsHierFn ).
89- mustBe (stringValue ()).
90- asStringVector ().
91- mustBe (singleElement (), RError .Message .SINGLE_STRING_TOO_LONG , msg , vecLenFn ).
92- findFirst ().
93- mustBe (nonEmpty ? lengthGt (0 ) : lengthGte (0 ), RError .Message .NON_EMPTY_STRING , msg );
99+ builder .mustBe (stringValue ()).
100+ asStringVector ().
101+ mustBe (singleElement (), RError .Message .SINGLE_STRING_TOO_LONG , msg , vecLenFn ).
102+ findFirst ().
103+ mustBe (nonEmpty ? lengthGt (0 ) : lengthGte (0 ), RError .Message .NON_EMPTY_STRING , msg );
94104 //@formatter:on
95105 }
96106
107+ private static void checkSingleString (Casts casts , int argNum , String argName , String msg , boolean nonEmpty , Function <Object , String > clsHierFn ,
108+ Function <Object , Integer > vecLenFn ) {
109+ checkSingleString (casts , argNum , argName , msg , nonEmpty , clsHierFn , vecLenFn , false );
110+ }
111+
97112 public abstract static class R_initMethodDispatch extends RExternalBuiltinNode .Arg1 {
98113
99114 static {
@@ -353,7 +368,7 @@ public abstract static class R_getGeneric extends RExternalBuiltinNode.Arg4 {
353368 Function <Object , String > clsHierFn = ClassHierarchyScalarNode ::get ;
354369 Function <Object , Integer > vecLenFn = arg -> ((RAbstractStringVector ) arg ).getLength ();
355370
356- checkSingleString (casts , 0 , "f" , "The argument \" f\" to getGeneric" , true , clsHierFn , vecLenFn );
371+ checkSingleString (casts , 0 , "f" , "The argument \" f\" to getGeneric" , true , clsHierFn , vecLenFn , true );
357372
358373 casts .arg (1 , "mustFind" ).asLogicalVector ().findFirst (RRuntime .LOGICAL_FALSE ).map (toBoolean ());
359374
@@ -362,6 +377,11 @@ public abstract static class R_getGeneric extends RExternalBuiltinNode.Arg4 {
362377 checkSingleString (casts , 3 , "package" , "The argument \" package\" to getGeneric" , false , clsHierFn , vecLenFn );
363378 }
364379
380+ @ Specialization
381+ protected Object getGeneric (RSymbol name , boolean mustFind , REnvironment env , String pckg ) {
382+ return getGeneric (name .getName (), mustFind , env , pckg );
383+ }
384+
365385 @ Specialization
366386 protected Object getGeneric (String name , boolean mustFind , REnvironment env , String pckg ) {
367387 Object value = getGenericInternal .executeObject (name , env , pckg );
@@ -399,7 +419,7 @@ protected Object getGeneric(String name, REnvironment env, String pckg) {
399419 }
400420 FrameDescriptor currentFrameDesc = currentFrame .getFrameDescriptor ();
401421 Object o = slotRead (currentFrame , currentFrameDesc , name );
402- if (o != null ) {
422+ if (o instanceof RAttributable ) {
403423 RAttributable vl = (RAttributable ) o ;
404424 boolean ok = false ;
405425 if (vl instanceof RFunction && getGenericAttrNode .execute (vl ) != null ) {
@@ -420,10 +440,6 @@ protected Object getGeneric(String name, REnvironment env, String pckg) {
420440 }
421441 rho = rho .getParent ();
422442 }
423-
424- // TODO: in GNU R there is additional code here that deals with the case of "name"
425- // being a symbol but at this point this case is not handled (even possible?) in
426- // FastR
427443 return generic == null ? RNull .instance : generic ;
428444 }
429445
0 commit comments