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

moosetechnology / VerveineJ / 23737250939

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

Pull #206

github

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

1973 of 3976 branches covered (49.62%)

Branch coverage included in aggregate %.

86 of 137 new or added lines in 5 files covered. (62.77%)

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
                try {
270
                setVariableDeclaredType(node, declaredType);
4✔
NEW
271
                } catch (ClassCastException e) {
×
NEW
272
                        throw e;
×
273
                }
1✔
274
                return true;
2✔
275
        }
276

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

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

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

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

320
                IBinding qualifierBinding = node.getQualifier().resolveBinding();
4✔
321

322
                if ((qualifierBinding != null) && (qualifierBinding.getKind() == IBinding.TYPE)) {
6✔
323
                        TType fmx = dico.referredType((ITypeBinding)qualifierBinding, (TNamedEntity) context.top());
9✔
324
                        addReference(node, fmx, (ITypeBinding) qualifierBinding);
6✔
325
                }
326

327
                return false;
2✔
328
        }
329

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

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

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

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

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

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

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