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

pmd / pmd / #3722

pending completion
#3722

push

github actions

adangel
Suppress MissingOverride for Chars::isEmpty (#4291)

67270 of 127658 relevant lines covered (52.7%)

0.53 hits per line

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

91.11
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/asm/ClassStubBuilder.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.lang.java.symbols.internal.asm;
6

7
import org.checkerframework.checker.nullness.qual.Nullable;
8
import org.objectweb.asm.AnnotationVisitor;
9
import org.objectweb.asm.ClassVisitor;
10
import org.objectweb.asm.FieldVisitor;
11
import org.objectweb.asm.MethodVisitor;
12
import org.objectweb.asm.Opcodes;
13
import org.objectweb.asm.Type;
14
import org.objectweb.asm.TypePath;
15
import org.objectweb.asm.TypeReference;
16

17
import net.sourceforge.pmd.lang.java.symbols.internal.asm.ExecutableStub.CtorStub;
18
import net.sourceforge.pmd.lang.java.symbols.internal.asm.ExecutableStub.MethodStub;
19

20
/**
21
 * Populates a {@link ClassStub} by reading a class file. Some info is
22
 * known by the ClassStub without parsing (like its internal name), so
23
 * we defer parsing until later. The class should be parsed only once.
24
 */
25
class ClassStubBuilder extends ClassVisitor {
26

27
    private final ClassStub myStub;
28
    private final String myInternalName;
29
    private final AsmSymbolResolver resolver;
30

31
    private boolean isInnerNonStaticClass = false;
1✔
32

33
    ClassStubBuilder(ClassStub stub, AsmSymbolResolver resolver) {
34
        super(AsmSymbolResolver.ASM_API_V);
1✔
35
        this.myStub = stub;
1✔
36
        this.myInternalName = stub.getInternalName();
1✔
37
        this.resolver = resolver;
1✔
38
    }
1✔
39

40
    @Override
41
    public void visit(int version, int access, String internalName, @Nullable String signature, String superName, String[] interfaces) {
42
        myStub.setModifiers(access, true);
1✔
43
        myStub.setHeader(signature, superName, interfaces);
1✔
44
    }
1✔
45

46
    @Override
47
    public AnnotationBuilderVisitor visitAnnotation(String descriptor, boolean visible) {
48
        return new AnnotationBuilderVisitor(myStub, resolver, visible, descriptor);
1✔
49
    }
50

51
    @Override
52
    public void visitOuterClass(String ownerInternalName, @Nullable String methodName, @Nullable String methodDescriptor) {
53
        isInnerNonStaticClass = true;
×
54
        // only for enclosing method
55
        ClassStub outer = resolver.resolveFromInternalNameCannotFail(ownerInternalName);
×
56
        myStub.setOuterClass(outer, methodName, methodDescriptor);
×
57
    }
×
58

59
    @Override
60
    public FieldVisitor visitField(int access, String name, String descriptor, @Nullable String signature, @Nullable Object value) {
61
        FieldStub field = new FieldStub(myStub, name, access, descriptor, signature, value);
1✔
62
        myStub.addField(field);
1✔
63
        return new FieldVisitor(AsmSymbolResolver.ASM_API_V) {
1✔
64
            @Override
65
            public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
66
                return new AnnotationBuilderVisitor(field, resolver, visible, descriptor);
1✔
67
            }
68

69
            @Override
70
            public AnnotationVisitor visitTypeAnnotation(int typeRef, @Nullable TypePath typePath, String descriptor, boolean visible) {
71
                assert new TypeReference(typeRef).getSort() == TypeReference.FIELD : typeRef;
1✔
72
                return new AnnotationBuilderVisitor.TypeAnnotBuilderImpl(resolver, field, typeRef, typePath, visible, descriptor);
1✔
73
            }
74
        };
75
    }
76

77
    /**
78
     * Visits information about an inner class. This inner class is not necessarily a member of the
79
     * class being visited.
80
     *
81
     * <p>Spec: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.6
82
     *
83
     * @param innerInternalName the internal name of an inner class (see {@link Type#getInternalName()}).
84
     * @param outerName         the internal name of the class to which the inner class belongs (see {@link
85
     *                          Type#getInternalName()}). May be {@literal null} for not member classes.
86
     * @param innerSimpleName   the (simple) name of the inner class inside its enclosing class. May be
87
     *                          {@literal null} for anonymous inner classes.
88
     * @param access            the access flags of the inner class as originally
89
     *                          declared in the enclosing class.
90
     */
91
    @Override
92
    public void visitInnerClass(String innerInternalName, @Nullable String outerName, @Nullable String innerSimpleName, int access) {
93
        if (myInternalName.equals(outerName) && innerSimpleName != null) { // not anonymous
1✔
94
            ClassStub member = resolver.resolveFromInternalNameCannotFail(innerInternalName, ClassStub.UNKNOWN_ARITY);
1✔
95
            member.setSimpleName(innerSimpleName);
1✔
96
            member.setModifiers(access, false);
1✔
97
            myStub.addMemberClass(member);
1✔
98
        } else if (myInternalName.equals(innerInternalName) && outerName != null) {
1✔
99
            // then it's specifying the enclosing class
100
            // (myStub is the inner class)
101
            ClassStub outer = resolver.resolveFromInternalNameCannotFail(outerName);
1✔
102
            myStub.setSimpleName(innerSimpleName);
1✔
103
            myStub.setModifiers(access, false);
1✔
104
            myStub.setOuterClass(outer, null, null);
1✔
105
            isInnerNonStaticClass = (Opcodes.ACC_STATIC & access) == 0;
1✔
106
        }
107
    }
1✔
108

109
    @Override
110
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
111
        if ((access & (Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE)) != 0) {
1✔
112
            // ignore synthetic methods
113
            return null;
1✔
114
        }
115

116
        if ("<clinit>".equals(name)) {
1✔
117
            return null;
1✔
118
        }
119

120

121
        ExecutableStub execStub;
122
        if ("<init>".equals(name)) {
1✔
123
            CtorStub ctor = new CtorStub(myStub, access, descriptor, signature, exceptions, isInnerNonStaticClass);
1✔
124
            myStub.addCtor(ctor);
1✔
125
            execStub = ctor;
1✔
126
        } else {
1✔
127
            MethodStub method = new MethodStub(myStub, name, access, descriptor, signature, exceptions);
1✔
128
            myStub.addMethod(method);
1✔
129
            execStub = method;
1✔
130
        }
131
        return new MethodInfoVisitor(execStub);
1✔
132
    }
133
}
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