1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.classfile.visitor;
22
23import proguard.classfile.*;
24
25/**
26 * This <code>MemberVisitor</code> lets a given <code>MemberVisitor</code>
27 * visit all members that have the same name and type as the visited methods
28 * in the class hierarchy of a given target class.
29 *
30 * @author Eric Lafortune
31 */
32public class SimilarMemberVisitor
33implements   MemberVisitor
34{
35    private final Clazz         targetClass;
36    private final boolean       visitThisMember;
37    private final boolean       visitSuperMembers;
38    private final boolean       visitInterfaceMembers;
39    private final boolean       visitOverridingMembers;
40    private final MemberVisitor memberVisitor;
41
42
43    /**
44     * Creates a new SimilarMemberVisitor.
45     * @param targetClass            the class in whose hierarchy to look for
46     *                               the visited class members.
47     * @param visitThisMember        specifies whether to visit the class
48     *                               members in the target class itself.
49     * @param visitSuperMembers      specifies whether to visit the class
50     *                               members in the super classes of the target
51     *                               class.
52     * @param visitInterfaceMembers  specifies whether to visit the class
53     *                               members in the interface classes of the
54     *                               target class.
55     * @param visitOverridingMembers specifies whether to visit the class
56     *                               members in the subclasses of the target
57     *                               class.
58     * @param memberVisitor          the <code>MemberVisitor</code> to which
59     *                               visits will be delegated.
60     */
61    public SimilarMemberVisitor(Clazz         targetClass,
62                                boolean       visitThisMember,
63                                boolean       visitSuperMembers,
64                                boolean       visitInterfaceMembers,
65                                boolean       visitOverridingMembers,
66                                MemberVisitor memberVisitor)
67    {
68        this.targetClass            = targetClass;
69        this.visitThisMember        = visitThisMember;
70        this.visitSuperMembers      = visitSuperMembers;
71        this.visitInterfaceMembers  = visitInterfaceMembers;
72        this.visitOverridingMembers = visitOverridingMembers;
73        this.memberVisitor          = memberVisitor;
74    }
75
76
77    // Implementations for MemberVisitor.
78
79    public void visitProgramField(ProgramClass programClass, ProgramField programField)
80    {
81        targetClass.hierarchyAccept(visitThisMember,
82                                    visitSuperMembers,
83                                    visitInterfaceMembers,
84                                    visitOverridingMembers,
85                                    new NamedFieldVisitor(programField.getName(programClass),
86                                                          programField.getDescriptor(programClass),
87                                                          memberVisitor));
88    }
89
90
91    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
92    {
93        targetClass.hierarchyAccept(visitThisMember,
94                                    visitSuperMembers,
95                                    visitInterfaceMembers,
96                                    visitOverridingMembers,
97                                    new NamedFieldVisitor(libraryField.getName(libraryClass),
98                                                          libraryField.getDescriptor(libraryClass),
99                                                          memberVisitor));
100    }
101
102
103    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
104    {
105        targetClass.hierarchyAccept(visitThisMember,
106                                    visitSuperMembers,
107                                    visitInterfaceMembers,
108                                    visitOverridingMembers,
109                                    new NamedMethodVisitor(programMethod.getName(programClass),
110                                                           programMethod.getDescriptor(programClass),
111                                                           memberVisitor));
112    }
113
114
115    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
116    {
117        targetClass.hierarchyAccept(visitThisMember,
118                                    visitSuperMembers,
119                                    visitInterfaceMembers,
120                                    visitOverridingMembers,
121                                    new NamedMethodVisitor(libraryMethod.getName(libraryClass),
122                                                           libraryMethod.getDescriptor(libraryClass),
123                                                           memberVisitor));
124    }
125}