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 * Super class 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    protected FieldGenOrMethodGen() {
058    }
059
060    /**
061     * @since 6.0
062     */
063    protected FieldGenOrMethodGen(final int accessFlags) { // TODO could this be package protected?
064        super(accessFlags);
065    }
066
067    protected void addAll(final Attribute[] attributes) {
068        if (attributes != null) {
069            Collections.addAll(attributeList, attributes);
070        }
071    }
072
073    /**
074     * @since 6.0
075     */
076    public void addAnnotationEntry(final AnnotationEntryGen ag) {
077        annotationList.add(ag);
078    }
079
080    /**
081     * Add an attribute to this method. Currently, the JVM knows about the 'Code', 'ConstantValue', 'Synthetic' and
082     * 'Exceptions' attributes. Other attributes will be ignored by the JVM but do no harm.
083     *
084     * @param a attribute to be added
085     */
086    public void addAttribute(final Attribute a) {
087        attributeList.add(a);
088    }
089
090    @Override
091    public Object clone() {
092        try {
093            return super.clone();
094        } catch (final CloneNotSupportedException e) {
095            throw new UnsupportedOperationException("Clone Not Supported", e); // never happens
096        }
097    }
098
099    public AnnotationEntryGen[] getAnnotationEntries() {
100        return annotationList.toArray(AnnotationEntryGen.EMPTY_ARRAY);
101    }
102
103    /**
104     * @return all attributes of this method.
105     */
106    public Attribute[] getAttributes() {
107        return attributeList.toArray(Attribute.EMPTY_ARRAY);
108    }
109
110    public ConstantPoolGen getConstantPool() {
111        return cp;
112    }
113
114    /**
115     * @return name of method/field.
116     */
117    @Override
118    public String getName() {
119        return name;
120    }
121
122    /**
123     * @return signature of method/field.
124     */
125    public abstract String getSignature();
126
127    @Override
128    public Type getType() {
129        return type;
130    }
131
132    /**
133     * @since 6.0
134     */
135    public void removeAnnotationEntries() {
136        annotationList.clear();
137    }
138
139    /**
140     * @since 6.0
141     */
142    public void removeAnnotationEntry(final AnnotationEntryGen ag) {
143        annotationList.remove(ag);
144    }
145
146    /**
147     * Remove an attribute.
148     */
149    public void removeAttribute(final Attribute a) {
150        attributeList.remove(a);
151    }
152
153    /**
154     * Remove all attributes.
155     */
156    public void removeAttributes() {
157        attributeList.clear();
158    }
159
160    public void setConstantPool(final ConstantPoolGen cp) { // TODO could be package-protected?
161        this.cp = cp;
162    }
163
164    @Override
165    public void setName(final String name) { // TODO could be package-protected?
166        this.name = name;
167    }
168
169    @Override
170    public void setType(final Type type) { // TODO could be package-protected?
171        if (type.getType() == Const.T_ADDRESS) {
172            throw new IllegalArgumentException("Type cannot be " + type);
173        }
174        this.type = type;
175    }
176}