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