• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moosetechnology / VerveineJ / 28802666890

06 Jul 2026 03:22PM UTC coverage: 52.722% (+0.06%) from 52.667%
28802666890

Pull #268

github

web-flow
Merge 88cf9c82a into 04fa886ba
Pull Request #268: Fix/267 class comment wrongly assigned to constructor

2027 of 4016 branches covered (50.47%)

Branch coverage included in aggregate %.

6 of 8 new or added lines in 1 file covered. (75.0%)

11 existing lines in 1 file now uncovered.

4480 of 8326 relevant lines covered (53.81%)

2.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.15
/app/src/main/java/fr/inria/verveine/extractor/java/visitors/refvisitors/VisitorAccessRef.java
1
package fr.inria.verveine.extractor.java.visitors.refvisitors;
2

3
import fr.inria.verveine.extractor.java.EntityDictionary;
4
import fr.inria.verveine.extractor.java.VerveineJOptions;
5
import fr.inria.verveine.extractor.java.utils.ImplicitVarBinding;
6
import fr.inria.verveine.extractor.java.utils.NodeTypeChecker;
7
import fr.inria.verveine.extractor.java.visitors.GetVisitedEntityAbstractVisitor;
8

9
import org.eclipse.jdt.core.dom.ASTNode;
10
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
11
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
12
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
13
import org.eclipse.jdt.core.dom.ArrayAccess;
14
import org.eclipse.jdt.core.dom.AssertStatement;
15
import org.eclipse.jdt.core.dom.Assignment;
16
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
17
import org.eclipse.jdt.core.dom.CompilationUnit;
18
import org.eclipse.jdt.core.dom.DoStatement;
19
import org.eclipse.jdt.core.dom.EnhancedForStatement;
20
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
21
import org.eclipse.jdt.core.dom.EnumDeclaration;
22
import org.eclipse.jdt.core.dom.Expression;
23
import org.eclipse.jdt.core.dom.FieldAccess;
24
import org.eclipse.jdt.core.dom.FieldDeclaration;
25
import org.eclipse.jdt.core.dom.ForStatement;
26
import org.eclipse.jdt.core.dom.IBinding;
27
import org.eclipse.jdt.core.dom.IVariableBinding;
28
import org.eclipse.jdt.core.dom.IfStatement;
29
import org.eclipse.jdt.core.dom.InfixExpression;
30
import org.eclipse.jdt.core.dom.Initializer;
31
import org.eclipse.jdt.core.dom.LambdaExpression;
32
import org.eclipse.jdt.core.dom.MethodDeclaration;
33
import org.eclipse.jdt.core.dom.MethodInvocation;
34
import org.eclipse.jdt.core.dom.PostfixExpression;
35
import org.eclipse.jdt.core.dom.PrefixExpression;
36
import org.eclipse.jdt.core.dom.QualifiedName;
37
import org.eclipse.jdt.core.dom.RecordDeclaration;
38
import org.eclipse.jdt.core.dom.ReturnStatement;
39
import org.eclipse.jdt.core.dom.SimpleName;
40
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
41
import org.eclipse.jdt.core.dom.SwitchCase;
42
import org.eclipse.jdt.core.dom.SwitchStatement;
43
import org.eclipse.jdt.core.dom.SynchronizedStatement;
44
import org.eclipse.jdt.core.dom.ThisExpression;
45
import org.eclipse.jdt.core.dom.ThrowStatement;
46
import org.eclipse.jdt.core.dom.TypeDeclaration;
47
import org.eclipse.jdt.core.dom.TypeLiteral;
48
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
49
import org.eclipse.jdt.core.dom.WhileStatement;
50
import org.moosetechnology.model.famix.famixjavaentities.Attribute;
51
import org.moosetechnology.model.famix.famixjavaentities.ContainerEntity;
52
import org.moosetechnology.model.famix.famixjavaentities.Enum;
53
import org.moosetechnology.model.famix.famixjavaentities.EnumValue;
54
import org.moosetechnology.model.famix.famixjavaentities.ImplicitVariable;
55
import org.moosetechnology.model.famix.famixjavaentities.LocalVariable;
56
import org.moosetechnology.model.famix.famixjavaentities.Method;
57
import org.moosetechnology.model.famix.famixjavaentities.Parameter;
58
import org.moosetechnology.model.famix.famixtraits.TAccess;
59
import org.moosetechnology.model.famix.famixtraits.TAttribute;
60
import org.moosetechnology.model.famix.famixtraits.TMethod;
61
import org.moosetechnology.model.famix.famixtraits.TNamedEntity;
62
import org.moosetechnology.model.famix.famixtraits.TStructuralEntity;
63
import org.moosetechnology.model.famix.famixtraits.TWithAttributes;
64

65
import java.util.List;
66

67
/**
68
 * A visitor that extracts accesses to variables.
69
 * One difficulty is that variable are often SimpleName nodes
70
 * But many other things are also SimpleName nodes (ex: name of an invoked method)
71
 * So we need to differentiate them. The choice has been made to do this in the parent nodes of the SimpleName nodes
72
 */
73
public class VisitorAccessRef extends GetVisitedEntityAbstractVisitor {
74

75
        /**
76
         * Whether a variable access is lhs (write) or not
77
         */
78
        protected boolean inAssignmentLHS = false;
3✔
79

80
        /**
81
         * Counts in how many nested lambdas we are
82
         * This is needed because Lambdas parameters are currently considered as local variables whereas JDT (rightly) reports them as parameters
83
         */
84
        private int inLambda = 0;
3✔
85

86
        /**
87
         * This variable indicates that the current class declaration is actually a record declaration
88
         * FIXME Temporary workaround because there is no FamixJavaRecord and we use FamixJavaClass
89
         */
90
        private boolean declarationIsRecord = false;
3✔
91

92
        public VisitorAccessRef(EntityDictionary dico, VerveineJOptions options) {
93
                super(dico, options);
4✔
94
                this.inLambda = 0;
3✔
95
        }
1✔
96

97
        // VISITOR METHODS
98

99
        @Override
100
        public boolean visit(CompilationUnit node) {
101
                visitCompilationUnit(node);
4✔
102
                return super.visit(node);
4✔
103
        }
104

105
        @Override
106
        public void endVisit(CompilationUnit node) {
107
                endVisitCompilationUnit(node);
3✔
108
        }
1✔
109

110
        @Override
111
        public boolean visit(TypeDeclaration node) {
112
                if (visitTypeDeclaration( node) != null) {
4!
113
                        return super.visit(node);
4✔
114
                } else {
115
                        return false;
×
116
                }
117
        }
118

119
        @Override
120
        public void endVisit(TypeDeclaration node) {
121
                endVisitTypeDeclaration(node);
3✔
122
        }
1✔
123

124
        @Override
125
        public boolean visit(RecordDeclaration node) {
126
                //System.err.println("TRACE, Visiting RecordDeclaration: "+node.getName().getIdentifier());
UNCOV
127
                if (visitTypeDeclaration( node) != null) {
×
UNCOV
128
                        declarationIsRecord = true;
×
UNCOV
129
                        return super.visit(node);
×
130
                } else {
131
                        return false;
×
132
                }
133
        }
134

135
        @Override
136
        public void endVisit(RecordDeclaration node) {
UNCOV
137
                declarationIsRecord = false;
×
138

UNCOV
139
                super.endVisit(node);
×
UNCOV
140
        }
×
141

142
        @Override
143
        public boolean visit(ClassInstanceCreation node) {
144
                possiblyAnonymousClassDeclaration( node);
3✔
145
        visitIfNotNull(node.getExpression());
4✔
146
        for (Object arg : node.arguments()) {
10✔
147
            if (NodeTypeChecker.isSimpleName((ASTNode) arg)) {
4✔
148
                visitIfNotNull((ASTNode) arg);
5✔
149
            }
150
            else {
151
                    ((ASTNode) arg).accept(this);
4✔
152
                        }
153
        }
1✔
154
        if (node.getAnonymousClassDeclaration() != null) {
3✔
155
            node.getAnonymousClassDeclaration().accept(this);
4✔
156
        }
157
                return false;
2✔
158
        }
159

160
        @SuppressWarnings("unchecked")
161
        @Override
162
        public boolean visit(AnonymousClassDeclaration node) {
163
                if (visitAnonymousClassDeclaration( node) != null) {
4!
164
            visitNodeList(node.bodyDeclarations());
4✔
165
        }
166

167
                        return false;
2✔
168

169
        }
170

171
        @Override
172
        public void endVisit(AnonymousClassDeclaration node) {
173
                endVisitAnonymousClassDeclaration( node);
3✔
174
        }
1✔
175

176
        @SuppressWarnings("unchecked")
177
        @Override
178
        public boolean visit(EnumDeclaration node) {
179
                if (visitEnumDeclaration( node) != null) {
4!
180
            // no need to visit node.enumConstants() in this visitor
181
            visitNodeList(node.bodyDeclarations());
4✔
182
        }
183
                return false;
2✔
184
        }
185

186
    @Override
187
        public void endVisit(EnumDeclaration node) {
188
                endVisitEnumDeclaration( node);
3✔
189
        }
1✔
190

191
        @Override
192
        public boolean visit(AnnotationTypeDeclaration node) {
193
                if (visitAnnotationTypeDeclaration( node) != null) {
4!
194
                        return super.visit(node);
4✔
195
                }
196
                else {
197
                        return false;
×
198
                }
199
        }
200

201
        @Override
202
        public void endVisit(AnnotationTypeDeclaration node) {
203
                endVisitAnnotationTypeDeclaration(node);
3✔
204
        }
1✔
205

206
        public boolean visit(AnnotationTypeMemberDeclaration node) {
207
                if (visitAnnotationTypeMemberDeclaration( node) != null) {
4!
208
            visitIfNotNull(node.getDefault());
4✔
209
        }
210
                return false;
2✔
211
        }
212

213
        public void endVisit(AnnotationTypeMemberDeclaration node) {
214
                this.context.popAnnotationMember();
4✔
215
                super.endVisit(node);
3✔
216
        }
1✔
217

218
        public boolean visit(MethodDeclaration node) {
219
                Method fmx = visitMethodDeclaration( node);
4✔
220

221
                if (fmx != null) {
2!
222
                        if (node.getBody() != null) {
3✔
223
                                context.setLastAccess(null);
4✔
224
                node.getBody().accept(this);
4✔
225
                        }
226
        }
227
        return false;
2✔
228
        }
229

230
        @Override
231
        public void endVisit(MethodDeclaration node) {
232
                endVisitMethodDeclaration(node);
3✔
233
        }
1✔
234

235
        @Override
236
        public boolean visit(Initializer node) {
237
                if (visitInitializer(node) != null) {
4!
238
                        node.getBody().accept(this);
4✔
239
                }
240
                return false;
2✔
241
        }
242

243
        @Override
244
        public void endVisit(Initializer node) {
245
                endVisitInitializer(node);
3✔
246
        }
1✔
247

248
    /**
249
         * <pre>
250
         * {@code
251
     * MethodInvocation ::=
252
     *      [ Expression . ]
253
     *          [ < Type { , Type } > ]
254
     *          Identifier ( [ Expression { , Expression } ] )
255
     * }
256
         * </pre>
257
         **/
258
        @Override
259
        public boolean visit(MethodInvocation node) {
260
        visitIfNotNull( node.getExpression());
4✔
261
        for (Object arg : node.arguments()) {
10✔
262
            visitIfNotNull((ASTNode) arg);
4✔
263
        }
1✔
264
                return false;  // already visited the interesting children
2✔
265
        }
266

267
        /**
268
         * Currently not defining lambdas. Only parse their body and consider their parameters as local variables
269
         * of the parent method
270
         *<pre>
271
         * {@code
272
         *  LambdaExpression:
273
         *     Identifier -> Body
274
         *     ( [ Identifier { , Identifier } ] ) -> Body
275
         *     ( [ FormalParameter { , FormalParameter } ] ) -> Body
276
         * }
277
         * </pre>
278
         */
279
        @Override
280
        public boolean visit(LambdaExpression node) {
281
                inLambda++;
6✔
282
                node.getBody().accept(this);
4✔
283
                inLambda--;
6✔
284
                return false;  // only visit body of lambda
2✔
285
        }
286

287
        /**
288
         *  FieldDeclaration ::=
289
         *     [Javadoc] { ExtendedModifier } Type VariableDeclarationFragment
290
         *          { , VariableDeclarationFragment } ;
291
         */
292
        @SuppressWarnings("unchecked")
293
        @Override
294
        public boolean visit(FieldDeclaration node) {
295
            if (hasInitBlock(node)) {   // true if hasInitializer + recovers EntityDictionary.INIT_BLOCK_NAME method
4✔
296
            visitNodeList(node.fragments());
4✔
297
        }
298
        return false;
2✔
299
        }
300

301
        @Override
302
        public void endVisit(FieldDeclaration node) {
303
                endVisitFieldDeclaration(node);
3✔
304
        }
1✔
305

306
        public boolean visit(EnumConstantDeclaration node) {
307
        return visitEnumConstantDeclaration(node);
×
308
        }
309

310
        public void endVisit(EnumConstantDeclaration node) {
311
                endVisitEnumConstantDeclaration(node);
×
312
        }
×
313

314
        public boolean visit(FieldAccess node) {
315
            visitIfNotNull(node.getExpression());
4✔
316
                TMethod accessor = this.context.topMethod();
4✔
317
                IVariableBinding bnd = node.resolveFieldBinding();
3✔
318
                // FIXME if bnd == null we have a problem
319
                ensureAccessedStructEntity(bnd, node.getName().getIdentifier(), /*typ*/null, /*owner*/null, accessor);
10✔
320
                TAccess lastAccess = context.getLastAccess();
4✔
321
                if ( (options.withAnchors(VerveineJOptions.AnchorOptions.assoc))
8!
322
                                // check that lastAccess corresponds to current one
323
                                && (lastAccess != null) && (lastAccess.getAccessor() == accessor)
4!
324
                                && ((TNamedEntity) (lastAccess.getCandidates().iterator().next())).getName().equals(node.getName().getIdentifier())) {
10✔
325
                        dico.addSourceAnchor(lastAccess, node);
6✔
326
                }
327
                return false;
2✔
328
        }
329

330
        /*
331
         * Could be a FieldAccess (see JDT javadoc: class FieldAccess) 
332
         */
333
        public boolean visit(QualifiedName node) {
334
                IBinding bnd = node.resolveBinding();
3✔
335
                if ( (bnd != null) && (bnd.getKind() == IBinding.VARIABLE) ) {
6✔
336
                        // could be a field or an enumValue
337
                        TMethod accessor = this.context.topMethod();
4✔
338
                        ensureAccessedStructEntity((IVariableBinding) bnd, node.getName().getIdentifier(), /*typ*/null,
11✔
339
                                        /*owner*/null, accessor);
340
                        TAccess lastAccess = context.getLastAccess();
4✔
341
                        if ( (options.withAnchors(VerveineJOptions.AnchorOptions.assoc))
8!
342
                                        // check that lastAccess corresponds to current one
343
                                        && (lastAccess != null) && (lastAccess.getAccessor() == accessor)
4!
344
                                        && (((TNamedEntity) (lastAccess.getCandidates().iterator().next())).getName().equals(node.getName().getIdentifier()))) {
10!
345
                                dico.addSourceAnchor(lastAccess, node);
6✔
346
                        }
347
                }
348
                return false;
2✔
349
        }
350

351
    @SuppressWarnings("unchecked")
352
    public boolean visit(InfixExpression node) {
353
        visitIfNotNull( node.getLeftOperand());
4✔
354
        visitIfNotNull( node.getRightOperand());
4✔
355
        if (node.hasExtendedOperands()) {
3✔
356
            for (Expression op : (List<Expression>) node.extendedOperands()) {
11✔
357
                visitIfNotNull( op);
3✔
358
            }
1✔
359
        }
360
        return false;
2✔
361
    }
362

363
    @Override
364
    public boolean visit(PrefixExpression node) {
365
        visitIfNotNull( node.getOperand());
4✔
366
        return false;
2✔
367
    }
368

369
    @Override
370
    public boolean visit(PostfixExpression node) {
371
        visitIfNotNull( node.getOperand());
4✔
372
        return false;
2✔
373
    }
374

375
        // "SomeClass.class"
376
        public boolean visit(TypeLiteral node) {
377
                Attribute accessed = dico.getFamixAttribute(null, "class", dico.getFamixMetaClass(null));
10✔
378
                if (accessed != null) {
2!
379
                        createAccess(/*accessor*/context.topMethod(), accessed, inAssignmentLHS);
8✔
380
                }
381

382
                return super.visit(node);
4✔
383
        }
384

385
        public boolean visit(AssertStatement node) {
386
        visitIfNotNull( node.getExpression());
×
387
        visitIfNotNull( node.getMessage());
×
388
                return false;
×
389
        }
390

391
        public boolean visit(Assignment node) {
392
        visitAssignment(node.getLeftHandSide(), node.getRightHandSide());
6✔
393
                return false;
2✔
394
        }
395

396
    public boolean visit(ArrayAccess node) {
397
                // an array might be accessed in writing (see visit(Assignment node) ),
398
                // but it's index is accessed in reading
399
                boolean tmp = inAssignmentLHS;
3✔
400

401
                node.getArray().accept(this);
4✔
402

403
                inAssignmentLHS = false;  // array index is not lhs of an assignement
3✔
404
        visitIfNotNull( node.getIndex());
4✔
405
                inAssignmentLHS = tmp;
3✔
406

407
                return false;
2✔
408
        }
409

410
        public boolean visit(DoStatement node) {
411
        visitIfNotNull( node.getExpression());
×
412
        node.getBody().accept(this);
×
413
                return false;
×
414
        }
415

416
        public boolean visit(EnhancedForStatement node) {
417
        visitIfNotNull( node.getExpression());
4✔
418
        node.getBody().accept(this);
4✔
419
        return false;
2✔
420
        }
421

422
        @SuppressWarnings("unchecked")
423
        public boolean visit(ForStatement node) {
424
        visitNodeList(node.initializers());
4✔
425
        visitIfNotNull( node.getExpression());
4✔
426
        visitNodeList(node.updaters());
4✔
427
        node.getBody().accept(this);
4✔
428
        return false;
2✔
429
    }
430

431
        public boolean visit(IfStatement node) {
432
        visitIfNotNull( node.getExpression());
4✔
433
        node.getThenStatement().accept(this);
4✔
434
        if (node.getElseStatement() != null) {
3✔
435
            node.getElseStatement().accept(this);
4✔
436
        }
437
        return false;
2✔
438
    }
439

440
        public boolean visit(ReturnStatement node) {
441
        visitIfNotNull( node.getExpression());
4✔
442
        return false;
2✔
443
        }
444

445
        public boolean visit(SwitchCase node) {
446
                for ( Expression expr : (List<Expression>)node.expressions()) {
11✔
447
                        expr.accept(this);
3✔
448
                }
1✔
449
        return false;
2✔
450
        }
451

452
        @SuppressWarnings("unchecked")
453
        public boolean visit(SwitchStatement node) {
454
        visitIfNotNull( node.getExpression());
4✔
455
        visitNodeList(node.statements());
4✔
456
        return false;
2✔
457
        }
458

459
        public boolean visit(SynchronizedStatement node) {
460
        visitIfNotNull(node.getExpression());
×
461
        node.getBody().accept(this);
×
462
        return false;
×
463
        }
464

465
        public boolean visit(WhileStatement node) {
466
        visitIfNotNull(node.getExpression());
4✔
467
        node.getBody().accept(this);
4✔
468
        return false;
2✔
469
        }
470

471
        @Override
472
        public boolean visit(ThrowStatement node) {
473
                visitIfNotNull( node.getExpression());
4✔
474
                return false;
2✔
475
        }
476

477
        @Override
478
        public boolean visit(ThisExpression node) {
479
                IBinding bnd = ImplicitVarBinding.getInstance(context.topMethod(), EntityDictionary.THIS_NAME);
6✔
480
                ImplicitVariable fmx = dico.ensureFamixImplicitVariable(
8✔
481
                                bnd, 
482
                                EntityDictionary.THIS_NAME,
483
                                this.context.topType(), 
3✔
484
                                context.topMethod());
1✔
485
                if (fmx != null) {
2!
486
                        TMethod accessor = this.context.topMethod();
4✔
487

488
                        createAccess(accessor, fmx, inAssignmentLHS);
6✔
489

490
                        TAccess lastAccess = context.getLastAccess();
4✔
491
                        if ( (options.withAnchors(VerveineJOptions.AnchorOptions.assoc)) && (lastAccess != null) ) {
7!
492
                                dico.addSourceAnchor(lastAccess, node.getParent());
7✔
493
                        }
494
                }
495

496
                return false;
2✔
497
        }
498

499
        @Override
500
        public boolean visit(SingleVariableDeclaration node) {
501
                if (node.getInitializer() != null) {
3!
502
            visitAssignment(node.getName(), node.getInitializer());
×
503
                }
504
                return false;
2✔
505
        }
506

507
        @Override
508
        public boolean visit(VariableDeclarationFragment node) {
509
                if (node.getInitializer() != null) {
3✔
510
            visitAssignment(node.getName(), node.getInitializer());
6✔
511
                }
512
                return false;
2✔
513
        }
514

515
        @Override
516
        public boolean visit(SimpleName node) {
517
        //System.err.println("visit(SimpleName)");
518
        IBinding bnd = node.resolveBinding();
3✔
519
        if ( (bnd != null) && (bnd.getKind() == IBinding.VARIABLE) && (context.topMethod() != null) ) {
10!
520
            // could be a variable, a field, an enumValue, ...
521
            TMethod accessor = this.context.topMethod();
4✔
522
            ensureAccessedStructEntity((IVariableBinding) bnd, node.getIdentifier(), /*typ*/null, /*owner*/null,
10✔
523
                    accessor);
524
            TAccess lastAccess = context.getLastAccess();
4✔
525
            if ( options.withAnchors(VerveineJOptions.AnchorOptions.assoc)
8✔
526
                    // check that lastAccess corresponds to current one
527
                    && (lastAccess != null) && (lastAccess.getAccessor() == accessor)
4!
528
                    && (((TNamedEntity) (lastAccess.getCandidates().iterator().next())).getName().equals(node.getIdentifier()))) {
9✔
529
                dico.addSourceAnchor(lastAccess, node);
6✔
530
            }
531
        }
532
                return false;
2✔
533
        }
534

535
        // UTILITY METHODS
536

537
        private void visitIfNotNull(ASTNode node) {
538
                if (node != null) {
2✔
539
                        node.accept(this);
3✔
540
                }
541
        }
1✔
542

543
        private void visitAssignment(Expression lhs, Expression rhs) {
544
                inAssignmentLHS = true;
3✔
545
                visitIfNotNull(lhs);
3✔
546
                inAssignmentLHS = false;
3✔
547

548
                visitIfNotNull(rhs);
3✔
549
        }
1✔
550

551
        private TStructuralEntity ensureAccessedStructEntity(IVariableBinding bnd, String name,
552
                                                                                                                 org.moosetechnology.model.famix.famixjavaentities.Type typ, ContainerEntity owner, TMethod accessor) {
553
                TStructuralEntity accessed = null;
2✔
554

555
                if (bnd == null) {
2✔
556
                        // no way to know if it should be an attribute, EnumValue, variable, ...
557
                        return null;
2✔
558
                } else {
559
                        bnd = bnd.getVariableDeclaration();
3✔
560
                }
561

562
                // could also test: "owner instanceof Enum" in case bnd == null
563
                if (bnd.isEnumConstant()) {
3✔
564
                        accessed = dico.ensureFamixEnumValue(bnd, name, (Enum) owner);
9✔
565
                } else if (bnd.isField()) {
3✔
566
                        if (declarationIsRecord) {
3!
UNCOV
567
                                accessed = findRecordField( name);
×
568
                        }
569
                        else {
570
                                accessed = dico.ensureFamixAttribute(bnd, name, typ, (TWithAttributes) owner);
9✔
571
                        }
572
                        if ((accessed != null) && (((Attribute) accessed).getParentType() == null)
6!
573
                                        && (((Attribute) accessed).getName().equals("length"))) {
×
574
                                // special case: length attribute of arrays in Java
575
                                ((Attribute) accessed).setParentType(dico.ensureFamixClassArray());
×
576
                        }
577
                } else if (bnd.isParameter() && notInALambda()) {
6✔
578
                        accessed = dico.ensureFamixParameter(bnd, name, typ, (Method) owner);
10✔
579
                } else {
580
                        // it seems it is a variable.
581
                        // if it is not already defined, we assume we are not interested
582
                        accessed = (TStructuralEntity) dico.getEntityByKey(bnd);
6✔
583
                }
584

585
                createAccess(accessor, accessed, inAssignmentLHS);
6✔
586

587
                return accessed;
2✔
588
        }
589

590
        /** finding the FamixJavaAttribute with <code>name</code>
591
         * this is necessary because in JDT (version 3.46.0) the binding for the declaration of a RecordComponent is different from the binding of the record Field used
592
         */
593
        private TStructuralEntity findRecordField(String name) {
UNCOV
594
                for (TStructuralEntity entity : ((org.moosetechnology.model.famix.famixjavaentities.Class)context.topType()).getAttributes()) {
×
UNCOV
595
                        if (entity.getName().equals(name)) {
×
UNCOV
596
                                return entity;
×
597
                        }
UNCOV
598
                }
×
599
                return null;
×
600
        }
601

602
        /**
603
         * Creates a FamixAccess between an accessor and an accessed. Checks before that we are not in a local access to ignore.
604
         *
605
         * @param accessor -- the method accessing
606
         * @param accessed -- the variable accessed
607
         * @param isLHS    -- whether the access occurs on the LeftHandSide of an assignement (and therefore is a write access)
608
         */
609
        private void createAccess(TMethod accessor, TStructuralEntity accessed, boolean isLHS) {
610
                // create local accesses?
611
                if ((accessed != null) && (accessor != null)) {
4✔
612
                        if (options.withLocals() || (! localVariable(accessed, accessor)) ) {
9✔
613
                                context.setLastAccess(
10✔
614
                                                dico.addFamixAccess(accessor, (TStructuralEntity) accessed, /*isWrite*/isLHS, context.getLastAccess()));
2✔
615
                        }
616
                }
617
        }
1✔
618

619
        private boolean localVariable(TStructuralEntity accessed, TMethod accessor) {
620
                // TODO see issue 11 (https://github.com/NicolasAnquetil/VerveineJ/issues/11)
621

622
                // This is ugly.. but it allows us to not rewrite method in generated code
623
                if (accessed instanceof ImplicitVariable) {
3✔
624
                        return false;
2✔
625
                } else if (accessed instanceof Attribute && ((Attribute) accessed).getParentType() == accessor) {
8!
626
                        return true;
×
627
                } else if (accessed instanceof EnumValue && ((EnumValue) accessed).getParentEnum() == accessor) {
8!
628
                        return true;
×
629
                } 
630
                // Benoit Verhaeghe: Has been removed between VerveineJ 3.0.0 and VerveineJ 3.0.1
631
                // else if (accessed instanceof GlobalVariable && ((GlobalVariable) accessed).getParentScope() == accessor) {
632
                //         return true;
633
                // } 
634
                else if (accessed instanceof ImplicitVariable && ((ImplicitVariable) accessed).getParentBehaviouralEntity() == accessor) {
3!
635
                        return true;
×
636
                } else if (accessed instanceof LocalVariable && ((LocalVariable) accessed).getParentBehaviouralEntity() == accessor) {
8!
637
                        return true;
2✔
638
                } else if (accessed instanceof Parameter && ((Parameter) accessed).getParentBehaviouralEntity() == accessor) {
8!
639
                        return true;
2✔
640
                }
641
                if (((TNamedEntity) accessor.getParentType()).getName().startsWith(EntityDictionary.ANONYMOUS_NAME_PREFIX)) {
7✔
642
                        return localVariable(accessed, ((Method) ((org.moosetechnology.model.famix.famixjavaentities.Type) accessor.getParentType()).getTypeContainer()));
9✔
643
                }
644
                return false;
2✔
645
        }
646

647
        protected boolean notInALambda() {
648
                return (inLambda == 0);
7✔
649
        }
650

651
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc