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 */
019
020package org.apache.bcel.classfile;
021
022import java.io.DataInput;
023import java.io.DataOutputStream;
024import java.io.IOException;
025
026import org.apache.bcel.Const;
027
028/**
029 * Entry of the parameters table.
030 * <p>
031 * Implements {@link Node} as of 6.7.0.
032 * </p>
033 *
034 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.24"> The class File Format :
035 *      The MethodParameters Attribute</a>
036 * @since 6.0
037 */
038public class MethodParameter implements Cloneable, Node {
039
040    /** Index of the CONSTANT_Utf8_info structure in the constant_pool table representing the name of the parameter */
041    private int nameIndex;
042
043    /** The access flags */
044    private int accessFlags;
045
046    /**
047     * Constructs a MethodParameter.
048     */
049    public MethodParameter() {
050    }
051
052    /**
053     * Constructs an instance from a DataInput.
054     *
055     * @param input Input stream.
056     * @throws IOException if an I/O error occurs.
057     * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file
058     */
059    MethodParameter(final DataInput input) throws IOException {
060        nameIndex = input.readUnsignedShort();
061        accessFlags = input.readUnsignedShort();
062    }
063
064    @Override
065    public void accept(final Visitor v) {
066        v.visitMethodParameter(this);
067    }
068
069    /**
070     * Creates a deep copy of this object.
071     *
072     * @return deep copy of this object.
073     */
074    public MethodParameter copy() {
075        try {
076            return (MethodParameter) clone();
077        } catch (final CloneNotSupportedException e) {
078            // TODO should this throw?
079        }
080        return null;
081    }
082
083    /**
084     * Dumps object to file stream on binary format.
085     *
086     * @param file Output file stream.
087     * @throws IOException if an I/O error occurs.
088     */
089    public final void dump(final DataOutputStream file) throws IOException {
090        file.writeShort(nameIndex);
091        file.writeShort(accessFlags);
092    }
093
094    /**
095     * Gets the access flags.
096     *
097     * @return the access flags.
098     */
099    public int getAccessFlags() {
100        return accessFlags;
101    }
102
103    /**
104     * Gets the name index.
105     *
106     * @return the name index.
107     */
108    public int getNameIndex() {
109        return nameIndex;
110    }
111
112    /**
113     * Gets the name of the parameter.
114     *
115     * @param constantPool The pool to query.
116     * @return Constant from the given pool.
117     */
118    public String getParameterName(final ConstantPool constantPool) {
119        if (nameIndex == 0) {
120            return null;
121        }
122        return constantPool.getConstantUtf8(nameIndex).getBytes();
123    }
124
125    /**
126     * Checks if this parameter is final.
127     *
128     * @return true if this parameter is final.
129     */
130    public boolean isFinal() {
131        return (accessFlags & Const.ACC_FINAL) != 0;
132    }
133
134    /**
135     * Checks if this parameter is mandated.
136     *
137     * @return true if this parameter is mandated.
138     */
139    public boolean isMandated() {
140        return (accessFlags & Const.ACC_MANDATED) != 0;
141    }
142
143    /**
144     * Checks if this parameter is synthetic.
145     *
146     * @return true if this parameter is synthetic.
147     */
148    public boolean isSynthetic() {
149        return (accessFlags & Const.ACC_SYNTHETIC) != 0;
150    }
151
152    /**
153     * Sets the access flags.
154     *
155     * @param accessFlags the access flags.
156     */
157    public void setAccessFlags(final int accessFlags) {
158        this.accessFlags = accessFlags;
159    }
160
161    /**
162     * Sets the name index.
163     *
164     * @param nameIndex the name index.
165     */
166    public void setNameIndex(final int nameIndex) {
167        this.nameIndex = nameIndex;
168    }
169}