@@ -19,7 +19,7 @@ import { markAsAssignment } from './built-in-assignment';
19
19
import { ReferenceType } from '../../../../../environments/identifier' ;
20
20
import type { InGraphIdentifierDefinition } from '../../../../../environments/identifier' ;
21
21
import { resolveByName } from '../../../../../environments/resolve-by-name' ;
22
- import type { ContainerIndex , ContainerIndicesCollection , ContainerParentIndex } from '../../../../../graph/vertex' ;
22
+ import type { ContainerIndices , ContainerIndicesCollection } from '../../../../../graph/vertex' ;
23
23
import type { RArgument } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-argument' ;
24
24
import { RoleInParent } from '../../../../../../r-bridge/lang-4.x/ast/model/processing/role' ;
25
25
import type { RAccess } from '../../../../../../r-bridge/lang-4.x/ast/model/nodes/r-access' ;
@@ -126,7 +126,7 @@ function processNumberBasedAccess<OtherInfo>(
126
126
name : RSymbol < OtherInfo & ParentInformation , string > ,
127
127
args : readonly RFunctionArgument < OtherInfo & ParentInformation > [ ] ,
128
128
rootId : NodeId ,
129
- config : { treatIndicesAsString : boolean ; } & ForceArguments ,
129
+ config : ForceArguments ,
130
130
head : RArgument < OtherInfo & ParentInformation > ,
131
131
) {
132
132
const existing = data . environment . current . memory . get ( ':=' ) ;
@@ -169,7 +169,7 @@ function processStringBasedAccess<OtherInfo>(
169
169
data : DataflowProcessorInformation < OtherInfo & ParentInformation > ,
170
170
name : RSymbol < OtherInfo & ParentInformation , string > ,
171
171
rootId : NodeId ,
172
- config : { treatIndicesAsString : boolean ; } & ForceArguments ,
172
+ config : ForceArguments ,
173
173
) {
174
174
const newArgs = [ ...args ] ;
175
175
// if the argument is a symbol, we convert it to a string for this perspective
@@ -191,18 +191,23 @@ function processStringBasedAccess<OtherInfo>(
191
191
} ;
192
192
}
193
193
}
194
-
194
+
195
195
const nonEmptyArgs = newArgs . filter ( arg => arg !== EmptyArgument ) ;
196
196
const accessedArg = nonEmptyArgs . find ( arg => arg . info . role === RoleInParent . Accessed ) ;
197
197
const accessArg = nonEmptyArgs . find ( arg => arg . info . role === RoleInParent . IndexAccess ) ;
198
+
199
+ const isNestedAccess = accessedArg ?. value ?. type === RType . Access ;
200
+ const isTopMostNestedAccess = isNestedAccess && accessedArg ?. lexeme === '$' ;
201
+ const shouldResolveIndices = ! isNestedAccess || ( isTopMostNestedAccess ) ;
198
202
let accessedIndicesCollection : ContainerIndicesCollection ;
199
- if ( accessArg !== undefined && accessedArg != undefined ) {
203
+ // wenn accessed arg lexem == $ -> top most
204
+ if ( shouldResolveIndices && accessArg !== undefined && accessedArg != undefined ) {
200
205
accessedIndicesCollection = resolveAccess ( accessedArg , [ accessArg ] , data . environment ) ;
206
+ console . log ( 'fully resolved' , `${ accessedArg . info . fullLexeme } $${ accessArg . lexeme } ` , 'to' , accessedIndicesCollection ?. flatMap ( indices => indices . indices ) ) ;
201
207
}
202
208
203
- const fnCall = processKnownFunctionCall ( { name, args : [ ] , rootId, data, forceArgs : config . forceArgs } , accessedIndicesCollection ) ;
204
- const accessedIndices = accessedIndicesCollection ?. flatMap ( indices => indices . indices ) ;
205
- referenceIndices ( accessedIndices , fnCall , name . info . id ) ;
209
+ const fnCall = processKnownFunctionCall ( { name, args : newArgs , rootId, data, forceArgs : config . forceArgs } , accessedIndicesCollection ) ;
210
+ referenceIndices ( accessedIndicesCollection , fnCall , name . info . id ) ;
206
211
return fnCall ;
207
212
}
208
213
@@ -228,32 +233,40 @@ function resolveAccess<OtherInfo>(
228
233
) : ContainerIndicesCollection {
229
234
let newAccessedArg : ArgTypes < OtherInfo > = accessedArg ;
230
235
// Unwrap access of top-level arg
231
- if ( accessedArg . type === RType . Argument && accessedArg . value ?. type === RType . Access ) {
236
+ if ( accessedArg . type === RType . Argument &&
237
+ ( accessedArg . value ?. type === RType . Access || accessedArg . value ?. type === RType . Symbol )
238
+ ) {
232
239
newAccessedArg = accessedArg . value ;
233
240
}
234
241
235
242
let indicesCollection : ContainerIndicesCollection = undefined ;
236
243
// Resolve access recursively
237
244
if ( newAccessedArg . type === RType . Access ) {
238
- const accesses = newAccessedArg . access . filter ( access => access !== EmptyArgument ) . map ( access => access as RArgument < OtherInfo & ParentInformation > ) ;
245
+ const accesses = newAccessedArg . access
246
+ . filter ( access => access !== EmptyArgument )
247
+ . map ( access => access as RArgument < OtherInfo & ParentInformation > ) ;
248
+
249
+ // Recursively resolve access until indices are fully resolved
239
250
const resolvedIndicesCollection = resolveAccess (
240
251
newAccessedArg . accessed as RAccess < OtherInfo & ParentInformation > ,
241
252
accesses ,
242
253
environment ,
243
254
) ;
244
- const subIndices = resolvedIndicesCollection ?. flatMap ( indices => indices . indices ) . filter ( indices => 'subIndices' in indices ) . flatMap ( indices => indices . subIndices ) ;
245
- const collection : ContainerIndicesCollection = subIndices ? [
246
- {
247
- indices : subIndices ,
248
- isSingleIndex : false ,
249
- }
250
- ] : undefined ;
251
- const accessedIndicesCollection = filterIndices ( collection , accessArgs ) ;
252
- indicesCollection = accessedIndicesCollection ;
253
- }
254
255
255
- // When access is fully resolved, apply access
256
- if ( newAccessedArg . type === RType . Symbol ) {
256
+ // Get sub-indices of resolved indices and filter them according to the accessArgs
257
+ const subIndices = resolvedIndicesCollection
258
+ ?. flatMap ( indices => indices . indices )
259
+ . filter ( indices => 'subIndices' in indices )
260
+ . flatMap ( indices => indices . subIndices ) ;
261
+ indicesCollection = filterIndices ( subIndices , accessArgs ) ;
262
+
263
+ // Get indices that are not single indices e.g. list definitions
264
+ // const multiIndexCollection = resolvedIndicesCollection?.filter(indices => !indices.isSingleIndex);
265
+ // if(multiIndexCollection) {
266
+ // indicesCollection?.concat(multiIndexCollection);
267
+ // }
268
+ } else if ( newAccessedArg . type === RType . Symbol ) {
269
+ // When access is fully resolved, apply access
257
270
indicesCollection = resolveSingleIndex ( newAccessedArg , accessArgs , environment ) ;
258
271
}
259
272
@@ -273,15 +286,17 @@ function resolveSingleIndex<OtherInfo>(
273
286
accessArg : Base < OtherInfo & ParentInformation > [ ] ,
274
287
environment : REnvironmentInformation ,
275
288
) : ContainerIndicesCollection {
276
- const resolvedAccessedArg = resolveByName ( accessedArg . lexeme , environment ) ;
277
- const indicesCollection = resolvedAccessedArg ?. flatMap ( param => ( param as InGraphIdentifierDefinition ) ?. indicesCollection ?? [ ] ) ;
289
+ const definitions = resolveByName ( accessedArg . lexeme , environment ) ;
290
+ const indicesCollection = definitions ?. flatMap ( def => ( def as InGraphIdentifierDefinition ) ?. indicesCollection ?? [ ] ) ;
278
291
const accessedIndicesCollection = filterIndices ( indicesCollection , accessArg ) ;
279
292
return accessedIndicesCollection ;
280
293
}
281
294
282
295
/**
283
296
* Filters the single indices of the {@link indicesCollection} according to the lexeme of the {@link accessArgs}.
284
297
*
298
+ * Only non-single-index indices are filtered.
299
+ *
285
300
* @param indicesCollection - The {@link ContainerIndicesCollection} to filter
286
301
* @param accessArgs - The arguments which are used to filter {@link indicesCollection}
287
302
* @returns The filtered copy of {@link indicesCollection}
@@ -292,15 +307,24 @@ function filterIndices<OtherInfo>(
292
307
) : ContainerIndicesCollection {
293
308
let accessedIndicesCollection : ContainerIndicesCollection = undefined ;
294
309
for ( const indices of indicesCollection ?? [ ] ) {
310
+ let containerIndices : ContainerIndices ;
311
+ // if(indices.isSingleIndex) {
295
312
const filteredIndices = indices . indices . filter ( index => accessArgs . some ( arg => arg . lexeme === index . lexeme ) ) ;
313
+
296
314
if ( filteredIndices . length == 0 ) {
297
315
continue ;
298
316
}
299
- accessedIndicesCollection ??= [ ] ;
300
- accessedIndicesCollection . push ( {
317
+
318
+ containerIndices = {
301
319
indices : filteredIndices ,
302
320
isSingleIndex : indices . isSingleIndex
303
- } ) ;
321
+ } ;
322
+ // } else {
323
+ // containerIndices = indices;
324
+ // }
325
+
326
+ accessedIndicesCollection ??= [ ] ;
327
+ accessedIndicesCollection . push ( containerIndices ) ;
304
328
}
305
329
return accessedIndicesCollection ;
306
330
}
@@ -314,13 +338,19 @@ function filterIndices<OtherInfo>(
314
338
* @param parentNodeId - {@link NodeId} of the parent from which the edge starts
315
339
*/
316
340
function referenceIndices (
317
- accessedIndices : ContainerIndex [ ] | undefined ,
341
+ accessedIndicesCollection : ContainerIndicesCollection ,
318
342
fnCall : ProcessKnownFunctionCallResult ,
319
343
parentNodeId : NodeId ,
320
344
) {
345
+ const accessedIndices = accessedIndicesCollection ?. flatMap ( indices => indices . indices ) ;
346
+
321
347
for ( const accessedIndex of accessedIndices ?? [ ] ) {
322
348
fnCall . information . graph . addEdge ( parentNodeId , accessedIndex . nodeId , EdgeType . Reads ) ;
323
- const accessedSubIndices = ( accessedIndex as ContainerParentIndex ) ?. subIndices ?? [ ] ;
324
- referenceIndices ( accessedSubIndices , fnCall , accessedIndex . nodeId ) ;
349
+ // const accessedSubIndices = ('subIndices' in accessedIndex) ? accessedIndex.subIndices : undefined;
350
+ // referenceIndices(accessedSubIndices, fnCall, accessedIndex.nodeId);
351
+ const accessedSubIndices = ( 'subIndices' in accessedIndex ) ? accessedIndex . subIndices . flatMap ( indices => indices . indices ) : undefined ;
352
+ for ( const accessedSubIndex of accessedSubIndices ?? [ ] ) {
353
+ fnCall . information . graph . addEdge ( accessedIndex . nodeId , accessedSubIndex . nodeId , EdgeType . Reads ) ;
354
+ }
325
355
}
326
356
}
0 commit comments