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

moosetechnology / VerveineJ / 22185271598

19 Feb 2026 02:12PM UTC coverage: 51.954% (+0.4%) from 51.544%
22185271598

push

github

web-flow
Merge pull request #199 from moosetechnology/initializers

Introducing initializers

1972 of 3976 branches covered (49.6%)

Branch coverage included in aggregate %.

105 of 127 new or added lines in 26 files covered. (82.68%)

1 existing line in 1 file now uncovered.

4343 of 8179 relevant lines covered (53.1%)

2.15 hits per line

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

81.36
/app/src/main/java/fr/inria/verveine/extractor/java/visitors/defvisitors/VisitorClassMethodDef.java
1
package fr.inria.verveine.extractor.java.visitors.defvisitors;
2

3
import java.security.MessageDigest;
4
import java.security.NoSuchAlgorithmException;
5
import java.util.ArrayList;
6
import java.util.Collection;
7
import java.util.List;
8

9
import org.apache.commons.codec.digest.DigestUtils;
10
import org.eclipse.jdt.core.dom.*;
11
import org.moosetechnology.model.famix.famixjavaentities.AnnotationType;
12
import org.moosetechnology.model.famix.famixjavaentities.AnnotationTypeAttribute;
13
import org.moosetechnology.model.famix.famixjavaentities.ContainerEntity;
14
import org.moosetechnology.model.famix.famixjavaentities.Method;
15
import org.moosetechnology.model.famix.famixjavaentities.ParametricClass;
16
import org.moosetechnology.model.famix.famixtraits.TMethod;
17
import org.moosetechnology.model.famix.famixtraits.TWithMethods;
18
import org.moosetechnology.model.famix.famixtraits.TWithTypes;
19

20
import fr.inria.verveine.extractor.java.EntityDictionary;
21
import fr.inria.verveine.extractor.java.VerveineJOptions;
22
import fr.inria.verveine.extractor.java.utils.StubBinding;
23
import fr.inria.verveine.extractor.java.utils.Util;
24
import fr.inria.verveine.extractor.java.visitors.GetVisitedEntityAbstractVisitor;
25

26
/**
27
 * AST Visitor that defines all the (Famix) entities of interest
28
 * Famix entities are stored in a Map along with the IBindings to which they correspond
29
 */
30
public class VisitorClassMethodDef extends GetVisitedEntityAbstractVisitor {
31

32
    protected MessageDigest md5;
33

34
    public VisitorClassMethodDef(EntityDictionary dico, VerveineJOptions options) {
35
                super( dico, options);
4✔
36
        try {
37
            md5 = MessageDigest.getInstance("MD5");
4✔
38
        } catch (NoSuchAlgorithmException e) {
×
39
            e.printStackTrace();
×
40
            md5 = null;
×
41
        }
1✔
42
    }
1✔
43

44
        // VISITOR METHODS
45

46
        @Override
47
        public boolean visit(CompilationUnit node) {
48
                visitCompilationUnit(node);
4✔
49
                return super.visit(node);
4✔
50
        }
51

52
        @Override
53
        public void endVisit(CompilationUnit node) {
54
                endVisitCompilationUnit(node);
3✔
55
        }
1✔
56

57
        /*
58
         * Can only be a class or interface declaration
59
         * Local type: see comment of visit(ClassInstanceCreation node)
60
         */
61
        @Override
62
        public boolean visit(TypeDeclaration node) {
63
                //                System.err.println("TRACE, Visiting TypeDeclaration: "+node.getName().getIdentifier());
64
                ITypeBinding bnd = (ITypeBinding) StubBinding.getDeclarationBinding(node);
4✔
65

66
                @SuppressWarnings("unchecked")
67
                List<TypeParameter> typeParameters = (List<TypeParameter>) node.typeParameters();
3✔
68

69
                // may be could use this.referredType instead of dico.ensureFamixClass ?
70
                org.moosetechnology.model.famix.famixtraits.TType fmx;
71
                if (bnd.isInterface()) {
3✔
72
                        fmx = dico.ensureFamixInterface(
7✔
73
                                bnd, 
74
                                /*name*/node.getName().getIdentifier(), 
4✔
75
                                (TWithTypes) 
76
                                /*owner*/context.top(), 
3✔
77
                                /*isGeneric*/typeParameters.size()>0,
6✔
78
                                node.getModifiers());
1✔
79
                } else if (dico.isThrowable(bnd)) {
5✔
80
                        fmx = dico.ensureFamixException(
7✔
81
                                bnd, 
82
                                /*name*/node.getName().getIdentifier(), 
4✔
83
                                (TWithTypes) 
84
                                /*owner*/context.top(), 
3✔
85
                                /*isGeneric*/typeParameters.size()>0,
4!
86
                                node.getModifiers());
1✔
87
                } else {
88
                        fmx = dico.ensureFamixClass(
6✔
89
                                        bnd, 
90
                                        /*name*/node.getName().getIdentifier(), 
4✔
91
                                        /*owner*/context.top(), 
2✔
92
                                        /*isGeneric*/typeParameters.size()>0,
6✔
93
                                        node.getModifiers());
1✔
94
                }
95
                if (fmx != null) {
2!
96
                        Util.recursivelySetIsStub(fmx, false);
3✔
97

98
                        // if it is a generic and some parameterizedTypes were created for it,
99
                        // they are marked as stub which is not right
100
                        if (typeParameters.size() > 0) {
3✔
101
                                for (ParametricClass candidate : dico.getEntityByName(ParametricClass.class,
14✔
102
                                                node.getName().getIdentifier())) {
2✔
103
                                        candidate.setIsStub(false);
4✔
104
                                }
1✔
105
                        }
106

107
                        this.context.pushType(fmx);
4✔
108

109
                        if (options.withAnchors()) {
4!
110
                                dico.addSourceAnchor(fmx, node);
6✔
111
                        }
112

113

114
                        return super.visit(node);
4✔
115
                } else {
116
                        return false;
×
117
                }
118
        }
119

120
        @Override
121
        public void endVisit(TypeDeclaration node) {
122
                this.context.popType();
4✔
123
                super.endVisit(node);
3✔
124
        }
1✔
125

126
        /**
127
         * See field {@link VisitorClassMethodDef#anonymousSuperTypeName}<br>
128
         * We could test if it is a local type (inner/anonymous) and not define it in case it does not make any reference
129
         * to anything outside its owner class. But it would be a lot of work for probably little gain.
130
         */
131
        @Override
132
        public boolean visit(ClassInstanceCreation node) {
133
                //                System.err.println("TRACE, Visiting ClassInstanceCreation: " + node);
134
                possiblyAnonymousClassDeclaration(node);
3✔
135
                return super.visit(node);
4✔
136
        }
137

138
        /**
139
         * See field {@link VisitorClassMethodDef#anonymousSuperTypeName}
140
         */
141
        @Override
142
        public boolean visit(AnonymousClassDeclaration node) {
143
                //                System.err.println("TRACE, Visiting AnonymousClassDeclaration");
144
                org.moosetechnology.model.famix.famixjavaentities.Type fmx;
145
                ITypeBinding bnd = (ITypeBinding) StubBinding.getDeclarationBinding(node);
4✔
146

147
                int modifiers = (bnd != null) ? bnd.getModifiers() : EntityDictionary.UNKNOWN_MODIFIERS;
6!
148
                if (bnd.isInterface()) {
3!
149
                        fmx = this.dico.ensureFamixInterface(
×
150
                                        bnd, Util.stringForAnonymousName(getAnonymousSuperTypeName(), context), 
×
151
                                        (ContainerEntity) 
152
                                        /*owner*/context.top(), 
×
153
                                        /*isGeneric*/false, 
154
                                        modifiers);
155
                } else {
156
                        fmx = this.dico.ensureFamixClass(
6✔
157
                                        bnd, Util.stringForAnonymousName(getAnonymousSuperTypeName(), context), 
6✔
158
                                        (ContainerEntity) 
159
                                        /*owner*/context.top(), 
4✔
160
                                        /*isGeneric*/false, 
161
                                        modifiers);
162
                }
163

164
                if (fmx != null) {
2!
165
                        Util.recursivelySetIsStub(fmx, false);
3✔
166

167
                        if (options.withAnchors()) {
4!
168
                                dico.addSourceAnchor(fmx, node);
6✔
169
                        }
170
                        this.context.pushType(fmx);
4✔
171
                        return super.visit(node);
4✔
172
                } else {
173
                        return false;
×
174
                }
175
        }
176

177
        @Override
178
        public void endVisit(AnonymousClassDeclaration node) {
179
                if (!anonymousSuperTypeName.empty()) {
4✔
180
                        anonymousSuperTypeName.pop();
4✔
181
                }
182
                this.context.popType();
4✔
183
                super.endVisit(node);
3✔
184
        }
1✔
185

186
        @Override
187
        public boolean visit(EnumDeclaration node) {
188
//                System.err.println("TRACE, Visiting EnumDeclaration: "+node.getName().getIdentifier());
189
                ITypeBinding bnd = (ITypeBinding) StubBinding.getDeclarationBinding(node);
4✔
190

191
                org.moosetechnology.model.famix.famixjavaentities.Enum fmx = dico.ensureFamixEnum(bnd, node.getName().getIdentifier(), (TWithTypes) context.top());
12✔
192
                if (fmx != null) {
2!
193
                        Util.recursivelySetIsStub(fmx, false);
3✔
194

195
                        this.context.pushType(fmx);
4✔
196
                        if (options.withAnchors()) {
4!
197
                                dico.addSourceAnchor(fmx, node);
6✔
198
                        }
199
                        return super.visit(node);
4✔
200
                } else {
201
                        return false;
×
202
                }
203
        }
204

205
        @Override
206
        public void endVisit(EnumDeclaration node) {
207
                this.context.popType();
4✔
208
                super.endVisit(node);
3✔
209
        }
1✔
210

211
        @Override
212
        public boolean visit(AnnotationTypeDeclaration node) {
213
                ITypeBinding bnd = node.resolveBinding();
3✔
214
                AnnotationType fmx = dico.ensureFamixAnnotationType(bnd, node.getName().getIdentifier(), (ContainerEntity) context.top());
12✔
215
                if (fmx != null) {
2!
216
                        Util.recursivelySetIsStub(fmx, false);
3✔
217
                        if (options.withAnchors()) {
4!
218
                                dico.addSourceAnchor(fmx, node);
6✔
219
                        }
220

221
                        context.pushType(fmx);
4✔
222
                        return super.visit(node);
4✔
223
                }
224
                else {
225
                        context.pushType(null);
×
226
                        return false;
×
227
                }
228
        }
229

230
        @Override
231
        public void endVisit(AnnotationTypeDeclaration node) {
232
                this.context.popType();
4✔
233
                super.endVisit(node);
3✔
234
        }
1✔
235

236
        /**
237
     * MethodDeclaration ::=
238
     *     [ Javadoc ] { ExtendedModifier } [ &lt; TypeParameter { , TypeParameter } &gt; ] ( Type | void )
239
     *         Identifier (
240
     *             [ ReceiverParameter , ] [ FormalParameter { , FormalParameter } ]
241
     *         ) { Dimension }
242
     *         [ throws Type { , Type } ]
243
     *         ( Block | ; )
244
     *  Also includes ConstructorDeclaration (same thing without return type)
245
     *
246
         * Local type: same as {@link VisitorClassMethodDef#visit(ClassInstanceCreation)}, 
247
         * we create it even if it is a local method because there are too many ways it can access external things
248
         */
249
        @SuppressWarnings("unchecked")
250
        @Override
251
        public boolean visit(MethodDeclaration node) {
252
                IMethodBinding bnd = (IMethodBinding) StubBinding.getDeclarationBinding(node);
4✔
253
        Collection<String> paramTypes = new ArrayList<>();
4✔
254
        for (SingleVariableDeclaration param : (List<SingleVariableDeclaration>) node.parameters()) {
11✔
255
            paramTypes.add( Util.jdtTypeName(param.getType()));
6✔
256
        }
1✔
257

258
                Method fmx = dico.ensureFamixMethod(
6✔
259
                                bnd, 
260
                                node.getName().getIdentifier(), 
6✔
261
                                paramTypes, 
262
                                /*returnType*/null, 
263
                                (TWithMethods) /*owner*/context.topType(), 
3✔
264
                                node.getModifiers());
1✔
265

266
                if (fmx != null) {
2!
267
                        fmx.setIsStub(false);
4✔
268
                        // fmx.setBodyHash(this.computeHashForMethodBody(node));
269

270
                        this.context.pushMethod(fmx);
4✔
271

272
                        if (options.withAnchors()) {
4!
273
                                dico.addSourceAnchor(fmx, node);
6✔
274
                        }
275

276
                        if (node.getBody() != null) {
3✔
277
                                context.setTopMethodCyclo(1);
4✔
278
                        }
279
                        return super.visit(node);
4✔
280
                } else {
281
                        this.context.pushMethod(null);
×
282
                        return false;
×
283
                }
284
        }
285

286
        private String computeHashForMethodBody(MethodDeclaration node) {
287
                Block body = node.getBody();
×
288
                if ( (body == null) || (md5 == null) ) {
×
289
            return "0";
×
290
        }
291
        byte[] bytes = node.getBody().toString().replaceAll("\\r|\\n|\\t", "").getBytes();
×
292

293
       return DigestUtils.md5Hex(bytes).toUpperCase();
×
294
        }
295

296
        @Override
297
        public void endVisit(MethodDeclaration node) {
298
                closeMethodDeclaration();
2✔
299
                super.endVisit(node);
3✔
300
        }
1✔
301

302
        /**
303
     * BodyDeclaration ::=
304
     *                [ ... ]
305
     *                 FieldDeclaration
306
     *                 Initializer
307
     *                 MethodDeclaration (for methods and constructors)
308
     * Initializer ::=
309
     *      [ static ] Block
310
     */
311
    @Override
312
        public boolean visit(Initializer node) {
313
                //                System.err.println("TRACE, Visiting Initializer: ");
314

315
                Method fmx = (Method) createInitBlock(Modifier.isStatic(node.getModifiers()), true);
10✔
316
                // init-block don't have return type so no need to create a reference from this class to the "declared return type" class when classSummary is TRUE
317
                // also no parameters specified here, so no references to create either
318

319
                if (fmx != null) {
2!
320
            dico.setMethodModifiers(fmx, node.getModifiers());
6✔
321
            if (options.withAnchors()) {
4!
322
                    dico.addSourceAnchor(fmx, node);
6✔
323
                        }
324

325
                        if (node.getBody() != null) {
3!
326
                                context.setTopMethodCyclo(1);
4✔
327
                        }
328

329
                        return super.visit(node);
4✔
330
                } else {
331
                        this.context.pushMethod(null);   // because endVisit(Initializer) will pop it out
×
332
                        return false;
×
333
                }
334
        }
335

336
        @Override
337
        public void endVisit(Initializer node) {
338
                closeMethodDeclaration();
2✔
339
                super.endVisit(node);
3✔
340
        }
1✔
341

342
        @SuppressWarnings("unchecked")
343
        @Override
344
        public boolean visit(EnumConstantDeclaration node) {
345
                for (Expression expr : (List<Expression>)node.arguments()) {
11✔
346
                        if (expr != null) {
2!
347
                                createInitBlock(true , false); // Enum Constants are static
7✔
348
                                break;  // we created the INIT_BLOCK, no need to look for other declaration that would only ensure the same creation
1✔
349
                        }
350
                }
×
351
                return super.visit(node);
4✔
352
        
353
        }
354

355
    public void endVisit(EnumConstantDeclaration node) {
356
        closeOptionalInitBlock();
2✔
357
    }
1✔
358

359
        @SuppressWarnings("unchecked")
360
        @Override
361
        public boolean visit(FieldDeclaration node) {
362
                boolean hasInitBlock = false;
2✔
363
                for (VariableDeclaration varDecl : (List<VariableDeclaration>)node.fragments() ) {
11✔
364
                        if (varDecl.getInitializer() != null) {
3✔
365
                                createInitBlock(Modifier.isStatic(node.getModifiers()), false);
9✔
366
                                hasInitBlock = true;
2✔
367
                                break;  // we created the INIT_BLOCK, no need to look for other declaration that would only ensure the same creation
1✔
368
                        }
369
                }
1✔
370
                return hasInitBlock;
2✔
371
        }
372

373
    public void endVisit(FieldDeclaration node) {
374
        closeOptionalInitBlock();
2✔
375
    }
1✔
376

377
        @Override
378
        public boolean visit(AnnotationTypeMemberDeclaration node) {
379
//                System.err.println("TRACE, Visiting AnnotationTypeMemberDeclaration: "+node.getName().getIdentifier());
380
                IMethodBinding bnd = node.resolveBinding();
3✔
381

382
                // note"Annotation members looks like methods, but they are closer to attributes
383
                AnnotationTypeAttribute fmx = dico.ensureFamixAnnotationTypeAttribute(bnd, node.getName().getIdentifier(), (AnnotationType) context.topType());
12✔
384
                if (fmx != null) {
2!
385
                        fmx.setIsStub(false);
4✔
386
                        if (options.withAnchors()) {
4!
387
                                dico.addSourceAnchor(fmx, node);
6✔
388
                        }
389

390
                        context.pushAnnotationMember(fmx);
4✔
391
                        return super.visit(node);
4✔
392
                } else {
393
                        context.pushAnnotationMember(null);
×
394
                        return false;
×
395
                }
396
        }
397

398
        @Override
399
        public void endVisit(AnnotationTypeMemberDeclaration node) {
400
                this.context.popAnnotationMember();
4✔
401
                super.endVisit(node);
3✔
402
        }
1✔
403

404
        @Override
405
        public boolean visit(ConstructorInvocation node) {
406
                //                System.err.println("TRACE, Visiting ConstructorInvocation: ");
407
                this.context.addTopMethodNOS(1);
4✔
408
                return super.visit(node);
4✔
409
        }
410

411
        @Override
412
        public boolean visit(SuperConstructorInvocation node) {
413
                this.context.addTopMethodNOS(1);
4✔
414
                return super.visit(node);
4✔
415
        }
416

417
        // "SomeClass.class"
418
        public boolean visit(TypeLiteral node) {
419
                dico.ensureFamixMetaClass(null);
5✔
420
                return false;
2✔
421
        }
422

423
        @Override
424
        public boolean visit(ThrowStatement node) {
425
                this.context.addTopMethodNOS(1);
4✔
426
                return super.visit(node);
4✔
427
        }
428

429
        @Override
430
        public boolean visit(CatchClause node) {
431
                this.context.addTopMethodCyclo(1);
4✔
432
                return super.visit(node);
4✔
433
        }
434

435
        @Override
436
        public boolean visit(AssertStatement node) {
437
                this.context.addTopMethodNOS(1);
×
438
                return super.visit(node);
×
439
        }
440

441
        @Override
442
        public boolean visit(Assignment node) {
443
                this.context.addTopMethodNOS(1);
4✔
444
                return super.visit(node);
4✔
445
        }
446

447
        @Override
448
        public boolean visit(ContinueStatement node) {
449
                this.context.addTopMethodNOS(1);
×
450
                return super.visit(node);
×
451
        }
452

453
        @Override
454
        public boolean visit(DoStatement node) {
455
                this.context.addTopMethodCyclo(1);
×
456
                this.context.addTopMethodNOS(1);
×
457
                return super.visit(node);
×
458
        }
459

460
        @Override
461
        public boolean visit(ExpressionStatement node) {
462
                this.context.addTopMethodNOS(1);
4✔
463
                return super.visit(node);
4✔
464
        }
465

466
        @Override
467
        public boolean visit(EnhancedForStatement node) {
468
                this.context.addTopMethodCyclo(1);
4✔
469
                this.context.addTopMethodNOS(1);
4✔
470
                return super.visit(node);
4✔
471
        }
472

473
        @Override
474
        public boolean visit(ForStatement node) {
475
                this.context.addTopMethodCyclo(1);
4✔
476
                this.context.addTopMethodNOS(1);
4✔
477
                return super.visit(node);
4✔
478
        }
479

480
        @Override
481
        public boolean visit(IfStatement node) {
482
                this.context.addTopMethodCyclo(1);
4✔
483
                this.context.addTopMethodNOS(1);
4✔
484
                return super.visit(node);
4✔
485
        }
486

487
        @Override
488
        public boolean visit(ReturnStatement node) {
489
                this.context.addTopMethodNOS(1);
4✔
490
                return super.visit(node);
4✔
491
        }
492

493
        @Override
494
        public boolean visit(SwitchCase node) {
495
                this.context.addTopMethodCyclo(1);
4✔
496
                this.context.addTopMethodNOS(1);
4✔
497
                return super.visit(node);
4✔
498
        }
499

500
        @Override
501
        public boolean visit(SwitchStatement node) {
502
                this.context.addTopMethodNOS(1);
4✔
503
                return super.visit(node);
4✔
504
        }
505

506
        @Override
507
        public boolean visit(SynchronizedStatement node) {
508
                this.context.addTopMethodNOS(1);
×
509
                return super.visit(node);
×
510
        }
511

512
        @Override
513
        public boolean visit(TryStatement node) {
514
                this.context.addTopMethodCyclo(1);
4✔
515
                this.context.addTopMethodNOS(1);
4✔
516
                return super.visit(node);
4✔
517
        }
518

519
        @Override
520
        public boolean visit(VariableDeclarationStatement node) {
521
                this.context.addTopMethodNOS(1);
4✔
522
                return super.visit(node);
4✔
523
        }
524

525
        @Override
526
        public boolean visit(WhileStatement node) {
527
                this.context.addTopMethodCyclo(1);
4✔
528
                this.context.addTopMethodNOS(1);
4✔
529
                return super.visit(node);
4✔
530
        }
531

532
        // UTILITY METHODS
533

534
    /**
535
     * REnsures the creation of the fake method: {@link EntityDictionary#INIT_BLOCK_NAME}
536
     *
537
     * Used in the case of instance/class initializer and initializing expressions of FieldDeclarations and EnumConstantDeclarations
538
         */
539
        protected TMethod createInitBlock(Boolean isStatic, Boolean isInitializationBlock) {
540
                // putting field's initialization code in an INIT_BLOCK_NAME method
541
                Method ctxtMeth = (Method) this.context.topMethod();
5✔
542
                if (ctxtMeth != null && !ctxtMeth.getIsInitializer() && ctxtMeth.getIsClassSide() != isStatic) {
10!
UNCOV
543
                        ctxtMeth = null;
×
544
                } else {
545
                        if (ctxtMeth != null && ctxtMeth.getParentType() != context.topType()) {
8!
546
                                /* We are in a field initialization in an anonymous class created in another field initialization.
547
                                 * In this example, we are in the declaration of aField2:
548
                                 * class Class1 {
549
                                 *         class Class2 {}
550
                                 *  Class2 aField1 = new Class2() {
551
                                 *                 Class3 aField2 = xyz;
552
                                 *   }
553
                                 * }
554
                                 *
555
                                 * This means we have to create the Initializer of the inner class (in the example above, Class2::<Initializer>).
556
                                 */
557
                                ctxtMeth = null;
2✔
558
                        }
559
                }
560
                if (ctxtMeth == null) {
2!
561
                        ctxtMeth = dico.ensureFamixInitializer(
6✔
562
                                        (TWithMethods) context.topType(), isStatic, isInitializationBlock);
4✔
563
                        ctxtMeth.setIsStub(false);
4✔
564
                        ctxtMeth.setIsDead(false);
3✔
565
                        // initialization block doesn't have return type so no need to create a reference from its class to the "declared return type" class when classSummary is TRUE
566
                        pushInitBlockMethod(ctxtMeth);
3✔
567
                }
568
                return ctxtMeth;
2✔
569
        }
570

571
        /**
572
         * Special method InitBlock may be "created" in various steps,
573
         * mainly when attributes are declared+initialized with the result of a method call.<br>
574
         * In such a case, we need to recover the previous metric values to add to them
575
         * @param ctxtMeth -- the InitBlock FamixMethod
576
         */
577
        protected void pushInitBlockMethod(TMethod ctxtMeth) {
578
                int nos = (ctxtMeth.getNumberOfStatements() == null) ? 0 : ctxtMeth.getNumberOfStatements().intValue();
9✔
579
                int cyclo = (ctxtMeth.getCyclomaticComplexity() == null) ? 0 : ctxtMeth.getCyclomaticComplexity().intValue();
9✔
580
                this.context.pushMethod(ctxtMeth);
4✔
581
                if ((nos != 0) || (cyclo != 0)) {
4!
582
                        context.setTopMethodNOS(nos);
4✔
583
                        context.setTopMethodCyclo(cyclo);
4✔
584
                }
585
        }
1✔
586

587
        protected void closeOptionalInitBlock() {
588
                Method ctxtMeth = (Method)this.context.topMethod();
5✔
589
                if ((ctxtMeth != null) && ctxtMeth.getIsInitializer() && !ctxtMeth.getIsConstructor()) {
10!
590
                        closeMethodDeclaration();
2✔
591
                }
592
        }
1✔
593

594
        /**
595
         * When closing a method declaration, we need to take care of some metrics that are also collected
596
         */
597
        protected void closeMethodDeclaration() {
598
                if (context.topMethod() != null) {
4!
599
                        int cyclo = context.getTopMethodCyclo();
4✔
600
                        int nos = context.getTopMethodNOS();
4✔
601
                        Method fmx = (Method) this.context.popMethod();
5✔
602
                        if (fmx != null) {
2!
603
                                fmx.setNumberOfStatements(nos);
4✔
604
                                fmx.setCyclomaticComplexity(cyclo);
4✔
605
                        }
606
                }
607
        }
1✔
608

609
}
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