001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.bcel.generic;
020
021import java.util.ArrayList;
022import java.util.Collections;
023import java.util.List;
024
025import org.apache.bcel.Const;
026import org.apache.bcel.classfile.AccessFlags;
027import org.apache.bcel.classfile.Attribute;
028
029/**
030 * Superclass for FieldGen and MethodGen objects, since they have some methods in common!
031 */
032public abstract class FieldGenOrMethodGen extends AccessFlags implements NamedAndTyped, Cloneable {
033
034    /**
035     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
036     */
037    @Deprecated
038    protected String name;
039
040    /**
041     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
042     */
043    @Deprecated
044    protected Type type;
045
046    /**
047     * @deprecated (since 6.0) will be made private; do not access directly, use getter/setter
048     */
049    @Deprecated
050    protected ConstantPoolGen cp;
051
052    private final List<Attribute> attributeList = new ArrayList<>();
053
054    // @since 6.0
055    private final List<AnnotationEntryGen> annotationList = new ArrayList<>();
056
057    /**
058     * Constructs a FieldGenOrMethodGen.
059     */
060    protected FieldGenOrMethodGen() {
061    }
062
063    /**
064     * Constructs a FieldGenOrMethodGen.
065     *
066     * @param accessFlags The access flags.
067     * @since 6.0
068     */
069    protected FieldGenOrMethodGen(final int accessFlags) { // TODO could this be package protected?
070        super(accessFlags);
071    }
072
073    /**
074     * Adds all attributes from an array.
075     *
076     * @param attributes The attributes to add.
077     */
078    protected void addAll(final Attribute[] attributes) {
079        if (attributes != null) {
080            Collections.addAll(attributeList, attributes);
081        }
082    }
083
084    /**
085     * Adds an annotation entry.
086     *
087     * @param ag The annotation entry.
088     * @since 6.0
089     */
090    public void addAnnotationEntry(final AnnotationEntryGen ag) {
091        annotationList.add(ag);
092    }
093
094    /**
095     * Add an attribute to this method. Currently, the JVM knows about the 'Code', 'ConstantValue', 'Synthetic' and
096     * 'Exceptions' attributes. Other attributes will be ignored by the JVM but do no harm.
097     *
098     * @param a attribute to be added.
099     */
100    public void addAttribute(final Attribute a) {
101        attributeList.add(a);
102    }
103
104    @Override
105    public Object clone() {
106        try {
107            return super.clone();
108        } catch (final CloneNotSupportedException e) {
109            throw new UnsupportedOperationException("Clone Not Supported", e); // never happens
110        }
111    }
112
113    /**
114     * Gets all annotation entries.
115     *
116     * @return all annotation entries.
117     */
118    public AnnotationEntryGen[] getAnnotationEntries() {
119        return annotationList.toArray(AnnotationEntryGen.EMPTY_ARRAY);
120    }
121
122    /**
123     * Gets all attributes of this method or field.
124     *
125     * @return all attributes of this method.
126     */
127    public Attribute[] getAttributes() {
128        return attributeList.toArray(Attribute.EMPTY_ARRAY);
129    }
130
131    /**
132     * Gets the constant pool.
133     *
134     * @return The constant pool.
135     */
136    public ConstantPoolGen getConstantPool() {
137        return cp;
138    }
139
140    /**
141     * Gets the name of the method or field.
142     *
143     * @return name of method/field.
144     */
145    @Override
146    public String getName() {
147        return name;
148    }
149
150    /**
151     * Gets the signature of method or field.
152     *
153     * @return signature of method/field.
154     */
155    public abstract String getSignature();
156
157    @Override
158    public Type getType() {
159        return type;
160    }
161
162    /**
163     * Removes all annotation entries.
164     *
165     * @since 6.0
166     */
167    public void removeAnnotationEntries() {
168        annotationList.clear();
169    }
170
171    /**
172     * Removes an annotation entry.
173     *
174     * @param ag The annotation entry to remove.
175     * @since 6.0
176     */
177    public void removeAnnotationEntry(final AnnotationEntryGen ag) {
178        annotationList.remove(ag);
179    }
180
181    /**
182     * Removes an attribute.
183     *
184     * @param a The attribute to remove.
185     */
186    public void removeAttribute(final Attribute a) {
187        attributeList.remove(a);
188    }
189
190    /**
191     * Removes all attributes.
192     */
193    public void removeAttributes() {
194        attributeList.clear();
195    }
196
197    /**
198     * Sets the constant pool.
199     *
200     * @param cp The constant pool.
201     */
202    public void setConstantPool(final ConstantPoolGen cp) { // TODO could be package-protected?
203        this.cp = cp;
204    }
205
206    @Override
207    public void setName(final String name) { // TODO could be package-protected?
208        this.name = name;
209    }
210
211    @Override
212    public void setType(final Type type) { // TODO could be package-protected?
213        if (type.getType() == Const.T_ADDRESS) {
214            throw new IllegalArgumentException("Type cannot be " + type);
215        }
216        this.type = type;
217    }
218}