@@ -23,6 +23,8 @@ internal class MemberReferenceResolver
23
23
private PerScopeCache scopeCache ;
24
24
private ILogger logger ;
25
25
private bool localsFetched ;
26
+ private int linqTypeId ;
27
+ private MonoSDBHelper sdbHelper ;
26
28
27
29
public MemberReferenceResolver ( MonoProxy proxy , ExecutionContext ctx , SessionId sessionId , int scopeId , ILogger logger )
28
30
{
@@ -32,6 +34,8 @@ public MemberReferenceResolver(MonoProxy proxy, ExecutionContext ctx, SessionId
32
34
this . ctx = ctx ;
33
35
this . logger = logger ;
34
36
scopeCache = ctx . GetCacheForScope ( scopeId ) ;
37
+ sdbHelper = proxy . SdbHelper ;
38
+ linqTypeId = - 1 ;
35
39
}
36
40
37
41
public MemberReferenceResolver ( MonoProxy proxy , ExecutionContext ctx , SessionId sessionId , JArray objectValues , ILogger logger )
@@ -43,6 +47,8 @@ public MemberReferenceResolver(MonoProxy proxy, ExecutionContext ctx, SessionId
43
47
this . logger = logger ;
44
48
scopeCache = new PerScopeCache ( objectValues ) ;
45
49
localsFetched = true ;
50
+ sdbHelper = proxy . SdbHelper ;
51
+ linqTypeId = - 1 ;
46
52
}
47
53
48
54
public async Task < JObject > GetValueFromObject ( JToken objRet , CancellationToken token )
@@ -51,7 +57,7 @@ public async Task<JObject> GetValueFromObject(JToken objRet, CancellationToken t
51
57
{
52
58
if ( DotnetObjectId . TryParse ( objRet ? [ "value" ] ? [ "objectId" ] ? . Value < string > ( ) , out DotnetObjectId objectId ) )
53
59
{
54
- var exceptionObject = await proxy . SdbHelper . GetObjectValues ( sessionId , int . Parse ( objectId . Value ) , true , false , false , true , token ) ;
60
+ var exceptionObject = await sdbHelper . GetObjectValues ( sessionId , int . Parse ( objectId . Value ) , GetObjectCommandOptions . WithProperties | GetObjectCommandOptions . OwnProperties , token ) ;
55
61
var exceptionObjectMessage = exceptionObject . FirstOrDefault ( attr => attr [ "name" ] . Value < string > ( ) . Equals ( "_message" ) ) ;
56
62
exceptionObjectMessage [ "value" ] [ "value" ] = objRet [ "value" ] ? [ "className" ] ? . Value < string > ( ) + ": " + exceptionObjectMessage [ "value" ] ? [ "value" ] ? . Value < string > ( ) ;
57
63
return exceptionObjectMessage [ "value" ] ? . Value < JObject > ( ) ;
@@ -67,8 +73,8 @@ public async Task<JObject> GetValueFromObject(JToken objRet, CancellationToken t
67
73
{
68
74
var commandParams = new MemoryStream ( ) ;
69
75
var commandParamsWriter = new MonoBinaryWriter ( commandParams ) ;
70
- commandParamsWriter . WriteObj ( objectId , proxy . SdbHelper ) ;
71
- var ret = await proxy . SdbHelper . InvokeMethod ( sessionId , commandParams . ToArray ( ) , objRet [ "get" ] [ "methodId" ] . Value < int > ( ) , objRet [ "name" ] . Value < string > ( ) , token ) ;
76
+ commandParamsWriter . WriteObj ( objectId , sdbHelper ) ;
77
+ var ret = await sdbHelper . InvokeMethod ( sessionId , commandParams . ToArray ( ) , objRet [ "get" ] [ "methodId" ] . Value < int > ( ) , objRet [ "name" ] . Value < string > ( ) , token ) ;
72
78
return await GetValueFromObject ( ret , token ) ;
73
79
}
74
80
@@ -88,27 +94,27 @@ public async Task<JObject> TryToRunOnLoadedClasses(string varName, CancellationT
88
94
classNameToFind += part . Trim ( ) ;
89
95
if ( typeId != - 1 )
90
96
{
91
- var fields = await proxy . SdbHelper . GetTypeFields ( sessionId , typeId , token ) ;
97
+ var fields = await sdbHelper . GetTypeFields ( sessionId , typeId , onlyPublic : false , token ) ;
92
98
foreach ( var field in fields )
93
99
{
94
100
if ( field . Name == part . Trim ( ) )
95
101
{
96
- var isInitialized = await proxy . SdbHelper . TypeIsInitialized ( sessionId , typeId , token ) ;
102
+ var isInitialized = await sdbHelper . TypeIsInitialized ( sessionId , typeId , token ) ;
97
103
if ( isInitialized == 0 )
98
104
{
99
- isInitialized = await proxy . SdbHelper . TypeInitialize ( sessionId , typeId , token ) ;
105
+ isInitialized = await sdbHelper . TypeInitialize ( sessionId , typeId , token ) ;
100
106
}
101
- var valueRet = await proxy . SdbHelper . GetFieldValue ( sessionId , typeId , field . Id , token ) ;
107
+ var valueRet = await sdbHelper . GetFieldValue ( sessionId , typeId , field . Id , token ) ;
102
108
return await GetValueFromObject ( valueRet , token ) ;
103
109
}
104
110
}
105
- var methodId = await proxy . SdbHelper . GetPropertyMethodIdByName ( sessionId , typeId , part . Trim ( ) , token ) ;
111
+ var methodId = await sdbHelper . GetPropertyMethodIdByName ( sessionId , typeId , part . Trim ( ) , token ) ;
106
112
if ( methodId != - 1 )
107
113
{
108
114
var commandParamsObj = new MemoryStream ( ) ;
109
115
var commandParamsObjWriter = new MonoBinaryWriter ( commandParamsObj ) ;
110
116
commandParamsObjWriter . Write ( 0 ) ; //param count
111
- var retMethod = await proxy . SdbHelper . InvokeMethod ( sessionId , commandParamsObj . ToArray ( ) , methodId , "methodRet" , token ) ;
117
+ var retMethod = await sdbHelper . InvokeMethod ( sessionId , commandParamsObj . ToArray ( ) , methodId , "methodRet" , token ) ;
112
118
return await GetValueFromObject ( retMethod , token ) ;
113
119
}
114
120
}
@@ -118,8 +124,8 @@ public async Task<JObject> TryToRunOnLoadedClasses(string varName, CancellationT
118
124
var type = asm . GetTypeByName ( classNameToFind ) ;
119
125
if ( type != null )
120
126
{
121
- var assemblyId = await proxy . SdbHelper . GetAssemblyId ( sessionId , type . assembly . Name , token ) ;
122
- typeId = await proxy . SdbHelper . GetTypeIdFromToken ( sessionId , assemblyId , type . Token , token ) ;
127
+ var assemblyId = await sdbHelper . GetAssemblyId ( sessionId , type . assembly . Name , token ) ;
128
+ typeId = await sdbHelper . GetTypeIdFromToken ( sessionId , assemblyId , type . Token , token ) ;
123
129
}
124
130
}
125
131
}
@@ -204,6 +210,7 @@ public async Task<JObject> Resolve(string varName, CancellationToken token)
204
210
public async Task < JObject > Resolve ( InvocationExpressionSyntax method , Dictionary < string , JObject > memberAccessValues , CancellationToken token )
205
211
{
206
212
var methodName = "" ;
213
+ int isTryingLinq = 0 ;
207
214
try
208
215
{
209
216
JObject rootObject = null ;
@@ -223,33 +230,56 @@ public async Task<JObject> Resolve(InvocationExpressionSyntax method, Dictionary
223
230
if ( rootObject != null )
224
231
{
225
232
DotnetObjectId . TryParse ( rootObject ? [ "objectId" ] ? . Value < string > ( ) , out DotnetObjectId objectId ) ;
226
- var typeId = await proxy . SdbHelper . GetTypeIdFromObject ( sessionId , int . Parse ( objectId . Value ) , true , token ) ;
227
- int methodId = await proxy . SdbHelper . GetMethodIdByName ( sessionId , typeId [ 0 ] , methodName , token ) ;
233
+ var typeIds = await sdbHelper . GetTypeIdFromObject ( sessionId , int . Parse ( objectId . Value ) , true , token ) ;
234
+ int methodId = await sdbHelper . GetMethodIdByName ( sessionId , typeIds [ 0 ] , methodName , token ) ;
235
+ var className = await sdbHelper . GetTypeNameOriginal ( sessionId , typeIds [ 0 ] , token ) ;
236
+ if ( methodId == 0 ) //try to search on System.Linq.Enumerable
237
+ {
238
+ if ( linqTypeId == - 1 )
239
+ linqTypeId = await sdbHelper . GetTypeByName ( sessionId , "System.Linq.Enumerable" , token ) ;
240
+ methodId = await sdbHelper . GetMethodIdByName ( sessionId , linqTypeId , methodName , token ) ;
241
+ if ( methodId != 0 )
242
+ {
243
+ foreach ( var typeId in typeIds )
244
+ {
245
+ var genericTypeArgs = await sdbHelper . GetTypeParamsOrArgsForGenericType ( sessionId , typeId , token ) ;
246
+ if ( genericTypeArgs . Count > 0 )
247
+ {
248
+ isTryingLinq = 1 ;
249
+ methodId = await sdbHelper . MakeGenericMethod ( sessionId , methodId , genericTypeArgs , token ) ;
250
+ break ;
251
+ }
252
+ }
253
+ }
254
+ }
228
255
if ( methodId == 0 ) {
229
- var typeName = await proxy . SdbHelper . GetTypeName ( sessionId , typeId [ 0 ] , token ) ;
256
+ var typeName = await sdbHelper . GetTypeName ( sessionId , typeIds [ 0 ] , token ) ;
230
257
throw new Exception ( $ "Method '{ methodName } ' not found in type '{ typeName } '") ;
231
258
}
232
259
var commandParamsObj = new MemoryStream ( ) ;
233
260
var commandParamsObjWriter = new MonoBinaryWriter ( commandParamsObj ) ;
234
- commandParamsObjWriter . WriteObj ( objectId , proxy . SdbHelper ) ;
261
+ if ( isTryingLinq == 0 )
262
+ commandParamsObjWriter . WriteObj ( objectId , sdbHelper ) ;
235
263
if ( method . ArgumentList != null )
236
264
{
237
- commandParamsObjWriter . Write ( ( int ) method . ArgumentList . Arguments . Count ) ;
265
+ commandParamsObjWriter . Write ( ( int ) method . ArgumentList . Arguments . Count + isTryingLinq ) ;
266
+ if ( isTryingLinq == 1 )
267
+ commandParamsObjWriter . WriteObj ( objectId , sdbHelper ) ;
238
268
foreach ( var arg in method . ArgumentList . Arguments )
239
269
{
240
270
if ( arg . Expression is LiteralExpressionSyntax )
241
271
{
242
- if ( ! await commandParamsObjWriter . WriteConst ( sessionId , arg . Expression as LiteralExpressionSyntax , proxy . SdbHelper , token ) )
272
+ if ( ! await commandParamsObjWriter . WriteConst ( sessionId , arg . Expression as LiteralExpressionSyntax , sdbHelper , token ) )
243
273
return null ;
244
274
}
245
275
if ( arg . Expression is IdentifierNameSyntax )
246
276
{
247
277
var argParm = arg . Expression as IdentifierNameSyntax ;
248
- if ( ! await commandParamsObjWriter . WriteJsonValue ( sessionId , memberAccessValues [ argParm . Identifier . Text ] , proxy . SdbHelper , token ) )
278
+ if ( ! await commandParamsObjWriter . WriteJsonValue ( sessionId , memberAccessValues [ argParm . Identifier . Text ] , sdbHelper , token ) )
249
279
return null ;
250
280
}
251
281
}
252
- var retMethod = await proxy . SdbHelper . InvokeMethod ( sessionId , commandParamsObj . ToArray ( ) , methodId , "methodRet" , token ) ;
282
+ var retMethod = await sdbHelper . InvokeMethod ( sessionId , commandParamsObj . ToArray ( ) , methodId , "methodRet" , token ) ;
253
283
return await GetValueFromObject ( retMethod , token ) ;
254
284
}
255
285
}
0 commit comments