@@ -408,6 +408,12 @@ public async Task<JObject> Resolve(
408408                        if  ( ! context . SdbAgent . ValueCreator . TryGetValueTypeById ( objectId . Value ,  out  ValueTypeClass  valueType ) ) 
409409                            throw  new  InvalidOperationException ( $ "Cannot apply indexing with [] to an expression of scheme '{ objectId . Scheme } '") ; 
410410                        var  typeInfo  =  await  context . SdbAgent . GetTypeInfo ( valueType . TypeId ,  token ) ; 
411+                         if  ( valueType . InlineArray  ==  null ) 
412+                         { 
413+                             JObject  vtResult  =  await  InvokeGetItemOnJObject ( rootObject ,  valueType . TypeId ,  objectId ,  elementIdxInfo ,  token ) ; 
414+                             if  ( vtResult  !=  null ) 
415+                                 return  vtResult ; 
416+                         } 
411417                        if  ( int . TryParse ( elementIdxInfo . ElementIdxStr ,  out  elementIdx )  &&  elementIdx  >=  0  &&  elementIdx  <  valueType . InlineArray . Count ) 
412418                            return  ( JObject ) valueType . InlineArray [ elementIdx ] [ "value" ] ; 
413419                        throw  new  InvalidOperationException ( $ "Index is outside the bounds of the inline array") ; 
@@ -436,34 +442,11 @@ public async Task<JObject> Resolve(
436442                        if  ( elementIdxInfo . Indexers  is  null  ||  elementIdxInfo . Indexers . Count  ==  0 ) 
437443                            throw  new  InternalErrorException ( $ "Unable to write index parameter to invoke the method in the runtime.") ; 
438444
439-                         var  typeIds  =  await  context . SdbAgent . GetTypeIdsForObject ( objectId . Value ,  true ,  token ) ; 
440-                         int [ ]  methodIds  =  await  context . SdbAgent . GetMethodIdsByName ( typeIds [ 0 ] ,  "get_Item" ,  BindingFlags . Default ,  token ) ; 
441-                         if  ( methodIds  ==  null  ||  methodIds . Length  ==  0 ) 
442-                             throw  new  InvalidOperationException ( $ "Type '{ rootObject ? [ "className" ] ? . Value < string > ( ) } ' cannot be indexed.") ; 
443- 
444-                         // ToDo: optimize the loop by choosing the right method at once without trying out them all 
445-                         for  ( int  i  =  0 ;  i  <  methodIds . Length ;  i ++ ) 
446-                         { 
447-                             MethodInfoWithDebugInformation  methodInfo  =  await  context . SdbAgent . GetMethodInfo ( methodIds [ i ] ,  token ) ; 
448-                             ParameterInfo [ ]  paramInfo  =  methodInfo . GetParametersInfo ( ) ; 
449-                             if  ( paramInfo . Length  ==  elementIdxInfo . DimensionsCount ) 
450-                             { 
451-                                 try 
452-                                 { 
453-                                     if  ( ! CheckParametersCompatibility ( paramInfo ,  elementIdxInfo . Indexers ) ) 
454-                                         continue ; 
455-                                     ArraySegment < byte >  buffer  =  await  WriteIndexObjectAsIndices ( objectId ,  elementIdxInfo . Indexers ,  paramInfo ) ; 
456-                                     JObject  getItemRetObj  =  await  context . SdbAgent . InvokeMethod ( buffer ,  methodIds [ i ] ,  token ) ; 
457-                                     return  ( JObject ) getItemRetObj [ "value" ] ; 
458-                                 } 
459-                                 catch  ( Exception  ex ) 
460-                                 { 
461-                                     logger . LogDebug ( $ "Attempt number { i  +  1 }  out of { methodIds . Length }  of invoking method { methodInfo . Name }  with parameter named { paramInfo [ 0 ] . Name }  on type { type }  failed. Method Id = { methodIds [ i ] } .\n Inner exception: { ex } .") ; 
462-                                     continue ; 
463-                                 } 
464-                             } 
465-                         } 
466-                         throw  new  InvalidOperationException ( $ "Cannot apply indexing with [] to an object of type '{ rootObject ? [ "className" ] ? . Value < string > ( ) } '") ; 
445+                         List < int >  typeIds  =  await  context . SdbAgent . GetTypeIdsForObject ( objectId . Value ,  true ,  token ) ; 
446+                         JObject  objResult  =  await  InvokeGetItemOnJObject ( rootObject ,  typeIds [ 0 ] ,  objectId ,  elementIdxInfo ,  token ) ; 
447+                         if  ( objResult  ==  null ) 
448+                             throw  new  InvalidOperationException ( $ "Cannot apply indexing with [] to an object of type '{ rootObject ? [ "className" ] ? . Value < string > ( ) } '") ; 
449+                         return  objResult ; 
467450                    default : 
468451                        throw  new  InvalidOperationException ( $ "Cannot apply indexing with [] to an expression of scheme '{ objectId . Scheme } '") ; 
469452                } 
@@ -543,6 +526,42 @@ async Task<ElementIndexInfo> GetElementIndexInfo(List<JObject> nestedIndexers)
543526                    ElementIdxStr :  elementIdxStr . ToString ( ) , 
544527                    Indexers :  indexers ) ; 
545528            } 
529+         } 
530+ 
531+         private  async  Task < JObject >  InvokeGetItemOnJObject ( 
532+             JObject  rootObject , 
533+             int  typeId , 
534+             DotnetObjectId  objectId , 
535+             ElementIndexInfo  elementIdxInfo , 
536+             CancellationToken  token ) 
537+         { 
538+             int [ ]  methodIds  =  await  context . SdbAgent . GetMethodIdsByName ( typeId ,  "get_Item" ,  BindingFlags . Default ,  token ) ; 
539+             if  ( methodIds  ==  null  ||  methodIds . Length  ==  0 ) 
540+                 throw  new  InvalidOperationException ( $ "Type '{ rootObject ? [ "className" ] ? . Value < string > ( ) } ' cannot be indexed.") ; 
541+             var  type  =  rootObject ? [ "type" ] ? . Value < string > ( ) ; 
542+ 
543+             // ToDo: optimize the loop by choosing the right method at once without trying out them all 
544+             for  ( int  i  =  0 ;  i  <  methodIds . Length ;  i ++ ) 
545+             { 
546+                 MethodInfoWithDebugInformation  methodInfo  =  await  context . SdbAgent . GetMethodInfo ( methodIds [ i ] ,  token ) ; 
547+                 ParameterInfo [ ]  paramInfo  =  methodInfo . GetParametersInfo ( ) ; 
548+                 if  ( paramInfo . Length  !=  elementIdxInfo . DimensionsCount ) 
549+                     continue ; 
550+                 try 
551+                 { 
552+                     if  ( ! CheckParametersCompatibility ( paramInfo ,  elementIdxInfo . Indexers ) ) 
553+                         continue ; 
554+                     ArraySegment < byte >  buffer  =  await  WriteIndexObjectAsIndices ( objectId ,  elementIdxInfo . Indexers ,  paramInfo ) ; 
555+                     JObject  getItemRetObj  =  await  context . SdbAgent . InvokeMethod ( buffer ,  methodIds [ i ] ,  token ) ; 
556+                     return  ( JObject ) getItemRetObj [ "value" ] ; 
557+                 } 
558+                 catch  ( Exception  ex ) 
559+                 { 
560+                     logger . LogDebug ( $ "Attempt number { i  +  1 }  out of { methodIds . Length }  of invoking method { methodInfo . Name }  with parameter named { paramInfo [ 0 ] . Name }  on type { type }  failed. Method Id = { methodIds [ i ] } .\n Inner exception: { ex } .") ; 
561+                     continue ; 
562+                 } 
563+             } 
564+             return  null ; 
546565
547566            async  Task < ArraySegment < byte > >  WriteIndexObjectAsIndices ( DotnetObjectId  rootObjId ,  List < object >  indexObjects ,  ParameterInfo [ ]  paramInfo ) 
548567            { 
@@ -578,19 +597,47 @@ private static bool CheckParametersCompatibility(ParameterInfo[] paramInfos, Lis
578597                return  false ; 
579598            foreach  ( ( ParameterInfo  paramInfo ,  object  indexObj )  in  paramInfos . Zip ( indexObjects ) ) 
580599            { 
581-                 // shouldn't we check LiteralExpressionSyntax for compatibility as well? 
582-                 if  ( indexObj  is  JObject  indexJObj  &&  ! CheckParameterCompatibility ( paramInfo . TypeCode ,  indexJObj ) ) 
600+                 string  argumentType  =  "" ,  argumentClassName  =  "" ; 
601+                 if  ( indexObj  is  JObject  indexJObj ) 
602+                 { 
603+                     argumentType  =  indexJObj [ "type" ] ? . Value < string > ( ) ; 
604+                     argumentClassName  =  indexJObj [ "className" ] ? . Value < string > ( ) ; 
605+                 } 
606+                 else  if  ( indexObj  is  LiteralExpressionSyntax  literal ) 
607+                 { 
608+                     // any primitive literal is an object 
609+                     if  ( paramInfo . TypeCode . Value  ==  ElementType . Object ) 
610+                         continue ; 
611+                     switch  ( literal . Kind ( ) ) 
612+                     { 
613+                         case  SyntaxKind . NumericLiteralExpression : 
614+                             argumentType  =  "number" ; 
615+                             break ; 
616+                         case  SyntaxKind . StringLiteralExpression : 
617+                             argumentType  =  "string" ; 
618+                             break ; 
619+                         case  SyntaxKind . TrueLiteralExpression : 
620+                         case  SyntaxKind . FalseLiteralExpression : 
621+                             argumentType  =  "boolean" ; 
622+                             break ; 
623+                         case  SyntaxKind . CharacterLiteralExpression : 
624+                             argumentType  =  "symbol" ; 
625+                             break ; 
626+                         case  SyntaxKind . NullLiteralExpression : 
627+                             // do not check 
628+                             continue ; 
629+                     } 
630+                 } 
631+                 if  ( ! CheckParameterCompatibility ( paramInfo . TypeCode ,  argumentType ,  argumentClassName ) ) 
583632                    return  false ; 
584633            } 
585634            return  true ; 
586635        } 
587636
588-         private  static bool  CheckParameterCompatibility ( ElementType ?  paramTypeCode ,  JObject   value ) 
637+         private  static bool  CheckParameterCompatibility ( ElementType ?  paramTypeCode ,  string   argumentType ,   string   argumentClassName = "" ) 
589638        { 
590639            if  ( ! paramTypeCode . HasValue ) 
591640                return  true ; 
592-             var  argumentType  =  value [ "type" ] ? . Value < string > ( ) ; 
593-             var  argumentClassName  =  value [ "className" ] ? . Value < string > ( ) ; 
594641
595642            switch  ( paramTypeCode . Value ) 
596643            { 
@@ -624,6 +671,8 @@ private static bool CheckParameterCompatibility(ElementType? paramTypeCode, JObj
624671                        return  false ; 
625672                    if  ( argumentType  ==  "object" ) 
626673                        return  false ; 
674+                     if  ( argumentType  ==  "string"  ||  argumentType  ==  "symbol" ) 
675+                         return  false ; 
627676                    break ; 
628677                case  ElementType . String : 
629678                    if  ( argumentType  !=  "string" ) 
0 commit comments