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

moosetechnology / VerveineJ / 23738394059

30 Mar 2026 09:44AM UTC coverage: 52.067% (+0.03%) from 52.039%
23738394059

Pull #206

github

web-flow
Merge 693daddfb into d564a6404
Pull Request #206: Array support

1973 of 3976 branches covered (49.62%)

Branch coverage included in aggregate %.

87 of 138 new or added lines in 5 files covered. (63.04%)

2 existing lines in 1 file now uncovered.

4388 of 8241 relevant lines covered (53.25%)

2.15 hits per line

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

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

3
import java.util.List;
4

5
import org.eclipse.jdt.core.dom.*;
6
import org.moosetechnology.model.famix.famixjavaentities.ContainerEntity;
7
import org.moosetechnology.model.famix.famixjavaentities.Method;
8
import org.moosetechnology.model.famix.famixjavaentities.Reference;
9
import org.moosetechnology.model.famix.famixtraits.*;
10

11
import fr.inria.verveine.extractor.java.EntityDictionary;
12
import fr.inria.verveine.extractor.java.VerveineJOptions;
13

14
public class VisitorTypeRefRef extends AbstractRefVisitor {
15

16
    /**
17
     * Global variable indicating whether a name could be a typeReference
18
     * Checked in visit(SimpleName), set in expressions that could contain typeReference
19
     */
20
        private boolean searchTypeRef;
21

22
        public VisitorTypeRefRef(EntityDictionary dictionary, VerveineJOptions options) {
23
                super(dictionary, options);
4✔
24
                this.searchTypeRef = false;
3✔
25
        }
1✔
26

27
        // VISITOR METHODS
28

29
        @Override
30
        public boolean visit(CompilationUnit node) {
31
                visitCompilationUnit(node);
4✔
32
                return super.visit(node);
4✔
33
        }
34

35
        @Override
36
        public void endVisit(CompilationUnit node) {
37
                endVisitCompilationUnit(node);
3✔
38
        }
1✔
39

40
        @Override
41
        public boolean visit(TypeDeclaration node) {
42
                if (visitTypeDeclaration(node) != null) {
4!
43
                        return super.visit(node);
4✔
44
                } else {
45
                        return false;
×
46
                }
47
        }
48

49
        @Override
50
        public void endVisit(TypeDeclaration node) {
51
                endVisitTypeDeclaration(node);
3✔
52
        }
1✔
53

54
        /** creation of an instance of a class (anonymous or not)<br>
55
         * <pre>ClassInstanceCreation ::=
56
        [ Expression . ]
57
            new [ &lt; Type { , Type } &gt; ]
58
            Type ( [ Expression { , Expression } ] )
59
            [ AnonymousClassDeclaration ]</pre><br>
60
         * we do not want to create a TypeReference (see <a href="https://github.com/moosetechnology/VerveineJ/issues/109">https://github.com/moosetechnology/VerveineJ/issues/109</a>
61
         * so we must prevent the visit to <code>node.getType()</code>
62
         * that's why we manually visit children instead of leaving that to JDT (and we return <code>false</code>) 
63
         */
64
        @SuppressWarnings("unchecked")
65
        @Override
66
        public boolean visit(ClassInstanceCreation node) {
67
                possiblyAnonymousClassDeclaration(node);
3✔
68

69
                if (node.getExpression() != null) {
3!
70
                        node.getExpression().accept(this);
×
71
                }
72
                for (Type typeArg : (List<Type>)node.typeArguments()) {
7!
73
                        typeArg.accept(this);
×
74
                }
×
75
                for (Expression arg : (List<Expression>)node.arguments()) {
11✔
76
                        arg.accept(this);
3✔
77
                }
1✔
78
                if (node.getAnonymousClassDeclaration() != null) {
3✔
79
                        node.getAnonymousClassDeclaration().accept(this);
4✔
80
                }
81

82
                return false;
2✔
83
        }
84

85
        @Override
86
        public boolean visit(AnonymousClassDeclaration node) {
87
                if (visitAnonymousClassDeclaration( node) != null) {
4!
88
                        return super.visit(node);
4✔
89
                }
90
                else {
91
                        return false;
×
92
                }
93
        }
94

95
        @Override
96
        public void endVisit(AnonymousClassDeclaration node) {
97
                endVisitAnonymousClassDeclaration( node);
3✔
98
        }
1✔
99

100
        @Override
101
        public boolean visit(EnumDeclaration node) {
102
                if (visitEnumDeclaration( node) != null) {
4!
103
                        return super.visit(node);
4✔
104
                }
105
                else {
106
                        return false;
×
107
                }
108
        }
109

110
        @Override
111
        public void endVisit(EnumDeclaration node) {
112
                endVisitEnumDeclaration( node);
3✔
113
        }
1✔
114

115
        @Override
116
        public boolean visit(AnnotationTypeDeclaration node) {
117
                if (visitAnnotationTypeDeclaration( node) != null) {
4!
118
                        return super.visit(node);
4✔
119
                }
120
                else {
121
                        return false;
×
122
                }
123
        }
124

125
        @Override
126
        public void endVisit(AnnotationTypeDeclaration node) {
127
                endVisitAnnotationTypeDeclaration(node);
3✔
128
        }
1✔
129

130
        public boolean visit(AnnotationTypeMemberDeclaration node) {
131
                if (visitAnnotationTypeMemberDeclaration( node) != null) {
4!
132
                        return super.visit(node);
4✔
133
                } else {
134
                        return false;
×
135
                }
136
        }
137

138
        public void endVisit(AnnotationTypeMemberDeclaration node) {
139
                this.context.popAnnotationMember();
4✔
140
                super.endVisit(node);
3✔
141
        }
1✔
142

143
        /**
144
         * Not visiting the AnnotationInstanceAttribute
145
         */
146
        @Override
147
        public boolean visit(SingleMemberAnnotation node) {
148
                return false;
2✔
149
        }
150

151
        /**
152
         * Not visiting the AnnotationInstanceAttribute
153
         */
154
        @Override
155
        public boolean visit(NormalAnnotation node) {
156
                return false;
2✔
157
        }
158

159
        /**
160
         * <pre>
161
         * {@code
162
         * MethodDeclaration ::=
163
    [ Javadoc ] { ExtendedModifier } [ < TypeParameter { , TypeParameter } > ] ( Type | void )
164
        Identifier (
165
            [ ReceiverParameter , ] [ FormalParameter { , FormalParameter } ]
166
        ) { Dimension }
167
        [ throws Type { , Type } ]
168
        ( Block | ; )
169
         * }
170
         * </pre>
171
         **/
172
        @SuppressWarnings("unchecked")
173
        public boolean visit(MethodDeclaration node) {
174
                Method fmx = visitMethodDeclaration( node);
4✔
175
                if (fmx != null) {
2!
176
                        if (! node.isConstructor()) {
3✔
177
                                ITypeBinding returnTypeBnd = (node.resolveBinding() == null) ? null : node.resolveBinding().getReturnType();
9✔
178
                                dico.ensureFamixEntityTyping(returnTypeBnd, fmx, dico.referredType(node.getReturnType2(), fmx, false));
13✔
179
                        }
180

181
                        //Parameters are visited by super!
182
                        return super.visit(node);
4✔
183
                }
184

185
                return false;
×
186
        }
187

188
        @Override
189
        public void endVisit(MethodDeclaration node) {
190
                endVisitMethodDeclaration(node);
3✔
191
        }
1✔
192

193
        /**
194
         * Initializer ::=
195
     *      [ static ] Block
196
     * Note:
197
     * VariableDeclarationFragment ::=
198
     *     Identifier { Dimension } [ = Expression ]
199
         */
200
        @Override
201
        public boolean visit(Initializer node) {
202
                if (visitInitializer(node) != null) {
4!
203
                        return super.visit(node);
4✔
204
                }
205
                else {
206
                        return false;
×
207
                }
208
        }
209

210
        @Override
211
        public void endVisit(Initializer node) {
212
                endVisitInitializer(node);
3✔
213
        }
1✔
214

215
        public boolean visit(InstanceofExpression node) {
216
                TType fmx = referredType(node.getRightOperand(), (ContainerEntity) context.top(), true);
10✔
217
                addReference( node, fmx, node.resolveTypeBinding());
6✔
218
                return super.visit(node);
4✔
219
        }
220

221
    /**
222
     *  FieldDeclaration ::=
223
     *     [Javadoc] { ExtendedModifier } Type VariableDeclarationFragment
224
     *          { , VariableDeclarationFragment } ;
225
     */
226
        @SuppressWarnings("unchecked")
227
        @Override
228
        public boolean visit(FieldDeclaration node) {
229
                hasInitBlock(node);  // to recover optional EntityDictionary.INIT_BLOCK_NAME method
4✔
230
                visitVariablesDeclaration((List<VariableDeclaration>)node.fragments(), node.getType());   // to create the TypeRefs
7✔
231
                return false;
2✔
232
        }
233

234
        @Override
235
        public void endVisit(FieldDeclaration node) {
236
                endVisitFieldDeclaration(node);
3✔
237
        }
1✔
238

239
        public boolean visit(EnumConstantDeclaration node) {
240
        return visitEnumConstantDeclaration(node);
4✔
241
        }
242

243
        public void endVisit(EnumConstantDeclaration node) {
244
                endVisitEnumConstantDeclaration(node);
3✔
245
        }
1✔
246

247
    @Override
248
    /* We are not dealing with the variable of the catch here but in VisitorExceptionRef
249
     * therefore we only visit the body of the catch
250
     */
251
    public boolean visit(CatchClause node) {
252
            node.getBody().accept(this);
4✔
253
        return false;
2✔
254
    }
255

256
        /**
257
         * SingleVariableDeclaration ::=
258
     *   { ExtendedModifier } Type {Annotation} [ ... ] Identifier { Dimension } [ = Expression ]
259
         */
260
        @Override
261
        public boolean visit(SingleVariableDeclaration node) {
262
                TType declaredType = null;
2✔
263
                if (node.isVarargs() || node.getExtraDimensions() > 0) {
6✔
264
                        declaredType = dico.ensureParametricArrayClass();
5✔
265
                }else {
266
                        declaredType = dico.referredType(node.getType().resolveBinding(), context.topType());
10✔
267
                }
268
                
269
                setVariableDeclaredType(node, declaredType);
4✔
270
                return true;
2✔
271
        }
272

273
        /**
274
         * VariableDeclarationExpression ::=
275
     *     { ExtendedModifier } Type VariableDeclarationFragment
276
     *          { , VariableDeclarationFragment }
277
         */
278
        @SuppressWarnings("unchecked")
279
        @Override
280
        public boolean visit(VariableDeclarationExpression node) {
281
                return visitVariablesDeclaration((List<VariableDeclaration>)node.fragments(), node.getType());
7✔
282
        }
283

284
        /**
285
         *  VariableDeclarationStatement ::=
286
     *     { ExtendedModifier } Type VariableDeclarationFragment
287
     *         { , VariableDeclarationFragment } ;
288
         */
289
        @SuppressWarnings("unchecked")
290
        @Override
291
        public boolean visit(VariableDeclarationStatement node) {
292
                return visitVariablesDeclaration((List<VariableDeclaration>)node.fragments(), node.getType());
7✔
293
        }
294

295
        public boolean visit(TypeLiteral node) {
296
                TType fmx = dico.referredType(node.getType(), (ContainerEntity) context.top(), true);
11✔
297
                
298
                ITypeBinding binding = null;
2✔
299
                if (node.getType().isArrayType()) {
4✔
300
                        binding = node.getType().resolveBinding();
5✔
301
                }else {
302
                        binding = node.resolveTypeBinding();
3✔
303
                }
304
                
305
                addReference(node, fmx, binding);
5✔
306
                return(false);
2✔
307
        }
308

309
        public boolean visit(QualifiedName node) {
310
                // if the context top is not a method, we don't deal with this QualifiedName
311
                // This might happen when a class inherits or implements a fully qualified name
312
                if (!(context.top() instanceof Method)) {
5✔
313
                        return false;
2✔
314
                }
315

316
                IBinding qualifierBinding = node.getQualifier().resolveBinding();
4✔
317

318
                if ((qualifierBinding != null) && (qualifierBinding.getKind() == IBinding.TYPE)) {
6✔
319
                        TType fmx = dico.referredType((ITypeBinding)qualifierBinding, (TNamedEntity) context.top());
9✔
320
                        addReference(node, fmx, (ITypeBinding) qualifierBinding);
6✔
321
                }
322

323
                return false;
2✔
324
        }
325

326
    @SuppressWarnings("unchecked")
327
        @Override
328
    public boolean visit(MethodInvocation node) {
329
            Expression receiver = node.getExpression();
3✔
330
        if (receiver != null) {
2✔
331
            searchTypeRef = true;
3✔
332
            receiver.accept(this);
3✔
333
            searchTypeRef = false;
3✔
334
        }
335
        for (Expression arg : (List<Expression>)node.arguments()) {
11✔
336
                        searchTypeRef = true;
3✔
337
            arg.accept(this);
3✔
338
                        searchTypeRef = false;
3✔
339
        }
1✔
340
        for (Type targ : (List<Type>)node.typeArguments()) {
7!
341
            searchTypeRef = true;
×
342
            targ.accept(this);
×
343
            searchTypeRef = false;
×
344
        }
×
345
        return false;
2✔
346
    }
347

348
    @Override
349
    public boolean visit(SimpleName node) {
350
            if (this.searchTypeRef) {
3✔
351
                        IBinding bnd = node.resolveBinding();
3✔
352
                        if ((bnd != null) && (bnd.getKind() == IBinding.TYPE)) {
6✔
353
                                org.moosetechnology.model.famix.famixtraits.TType referred = (org.moosetechnology.model.famix.famixtraits.TType) referredType((ITypeBinding) bnd, (ContainerEntity) context.top(), !((ITypeBinding) bnd).isEnum());
16✔
354
                                Reference ref = dico.addFamixReference((Method) context.top(), referred, context.getLastReference(), (ITypeBinding) bnd);
14✔
355
                                context.setLastReference(ref);
4✔
356
                                if ((options.withAnchors(VerveineJOptions.AnchorOptions.assoc)) && (ref != null) ) {
7!
357
                                        dico.addSourceAnchor(ref, node);
6✔
358
                                }
359
                        }
360
                }
361
        return false;
2✔
362
    }
363
/**
364
         * <pre>
365
         * {@code
366
         * CastExpression ::=
367
         *  ( Type ) Expression
368
         * }
369
         * </pre>
370
         */
371
        public boolean visit(CastExpression node) {
372
                ITypeBinding bnd = node.getType().resolveBinding();
4✔
373
                if (bnd != null) {
2!
374
                        org.moosetechnology.model.famix.famixtraits.TType referred = (org.moosetechnology.model.famix.famixtraits.TType) referredType(bnd, null, !bnd.isEnum());
10!
375
                        Reference ref = dico.addFamixReference((Method) context.top(), referred, context.getLastReference(), bnd);
13✔
376
                        context.setLastReference(ref);
4✔
377
                        if ((options.withAnchors(VerveineJOptions.AnchorOptions.assoc)) && (ref != null) ) {
7!
378
                                dico.addSourceAnchor(ref, node);
6✔
379
                        }
380
                }                return true;
2✔
381
         }
382

383
    /**
384
         * same behaviour for VariableDeclarationStatement and VariableDeclarationExpression
385
     * VariableDeclaration ::=
386
     *     SingleVariableDeclaration VariableDeclarationFragment
387
         */
388
        @SuppressWarnings("unchecked")
389
        private <T extends TWithTypes & TNamedEntity> boolean visitVariablesDeclaration(List<VariableDeclaration> fragments, Type declType) {
390
                for (VariableDeclaration varDecl : fragments) {
10✔
391
                        
392
                        TType declaredType = null;
2✔
393
                        if (varDecl.getExtraDimensions() > 0) {
3✔
394
                                declaredType = dico.ensureParametricArrayClass();
5✔
395
                        } else {
396
                                declaredType = dico.referredType(declType.resolveBinding(), (T) context.topType());
11✔
397
                        }
398
                        try {
399
                        setVariableDeclaredType(varDecl, declaredType);
4✔
NEW
400
                        } catch (ClassCastException e) {
×
NEW
401
                                throw e;
×
402
                        }
1✔
403
                        varDecl.accept(this);
3✔
404
                }
1✔
405
                return false;
2✔
406
        }
407

408
        protected void setVariableDeclaredType(VariableDeclaration var, TType varTyp) {
409
                TTypedEntity fmx = (TTypedEntity) dico.getEntityByKey(var.resolveBinding());
7✔
410
                if (fmx != null) {
2✔
411
                        dico.ensureFamixEntityTyping(var.resolveBinding().getType(), fmx, varTyp);
9✔
412
                }
413
        }
1✔
414

415
        /**
416
         * creates a <code>Reference</code> to the Famix <code>TType</code> from the current method (<code>context.top()</code>)
417
         *
418
         * <code>node</code> might be required to get the <code>sourceAnchor</code> of the <code>Reference</code>
419
         */
420
        protected void addReference( ASTNode node, TType fmx, ITypeBinding bnd) {
421
                Reference ref = dico.addFamixReference((Method) context.top(), fmx, context.getLastReference(), bnd);
13✔
422

423
                context.setLastReference(ref);
4✔
424
                if (options.withAnchors(VerveineJOptions.AnchorOptions.assoc)) {
5✔
425
                        dico.addSourceAnchor(ref, node);
6✔
426
        }
427

428
        }
1✔
429
}
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