    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}