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.constant;
22
23import proguard.classfile.*;
24import proguard.classfile.constant.visitor.ConstantVisitor;
25import proguard.classfile.visitor.*;
26
27/**
28 * This Constant represents a string constant in the constant pool.
29 *
30 * @author Eric Lafortune
31 */
32public class StringConstant extends Constant
33{
34    public int u2stringIndex;
35
36    /**
37     * An extra field pointing to the referenced Clazz object, if this
38     * string is being used in Class.forName(), .class, or
39     * Class.getDeclaredField/Method constructs.
40     * This field is typically filled out by the <code>{@link
41     * proguard.classfile.util.DynamicClassReferenceInitializer
42     * DynamicClassReferenceInitializer}</code> or by the <code>{@link
43     * proguard.classfile.util.DynamicMemberReferenceInitializer
44     * DynamicMemberReferenceInitializer}</code>.
45     */
46    public Clazz referencedClass;
47
48    /**
49     * An extra field pointing to the referenced Member object, if this
50     * string is being used in Class.getDeclaredField/Method constructs.
51     * This field is typically filled out by the <code>{@link
52     * proguard.classfile.util.DynamicMemberReferenceInitializer
53     * DynamicMemberReferenceInitializer}</code>.
54     */
55    public Member referencedMember;
56
57    /**
58     * An extra field pointing to the java.lang.String Clazz object.
59     * This field is typically filled out by the <code>{@link
60     * proguard.classfile.util.ClassReferenceInitializer
61     * ClassReferenceInitializer}</code>..
62     */
63    public Clazz javaLangStringClass;
64
65
66    /**
67     * Creates an uninitialized StringConstant.
68     */
69    public StringConstant()
70    {
71    }
72
73
74    /**
75     * Creates a new StringConstant with the given string index.
76     * @param u2stringIndex   the index of the string in the constant pool.
77     * @param referencedClass the referenced class, if any.
78     * @param referenceMember the referenced class member, if any.
79     */
80    public StringConstant(int    u2stringIndex,
81                          Clazz  referencedClass,
82                          Member referenceMember)
83    {
84        this.u2stringIndex    = u2stringIndex;
85        this.referencedClass  = referencedClass;
86        this.referencedMember = referenceMember;
87    }
88
89
90    /**
91     * Returns the string value.
92     */
93    public String getString(Clazz clazz)
94    {
95        return clazz.getString(u2stringIndex);
96    }
97
98
99    // Implementations for Constant.
100
101    public int getTag()
102    {
103        return ClassConstants.CONSTANT_String;
104    }
105
106    public void accept(Clazz clazz, ConstantVisitor constantVisitor)
107    {
108        constantVisitor.visitStringConstant(clazz, this);
109    }
110
111
112    /**
113     * Lets the referenced class accept the given visitor.
114     */
115    public void referencedClassAccept(ClassVisitor classVisitor)
116    {
117        if (referencedClass  != null &&
118            referencedMember == null)
119        {
120            referencedClass.accept(classVisitor);
121        }
122    }
123
124
125    /**
126     * Lets the referenced member accept the given visitor.
127     */
128    public void referencedMemberAccept(MemberVisitor memberVisitor)
129    {
130        if (referencedMember != null)
131        {
132            referencedMember.accept(referencedClass, memberVisitor);
133        }
134    }
135}
136