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    public MethodParameter() {
047    }
048
049    /**
050     * Constructs an instance from a DataInput.
051     *
052     * @param input Input stream
053     * @throws IOException if an I/O error occurs.
054     * @throws ClassFormatException if a class is malformed or cannot be interpreted as a class file
055     */
056    MethodParameter(final DataInput input) throws IOException {
057        nameIndex = input.readUnsignedShort();
058        accessFlags = input.readUnsignedShort();
059    }
060
061    @Override
062    public void accept(final Visitor v) {
063        v.visitMethodParameter(this);
064    }
065
066    /**
067     * @return deep copy of this object
068     */
069    public MethodParameter copy() {
070        try {
071            return (MethodParameter) clone();
072        } catch (final CloneNotSupportedException e) {
073            // TODO should this throw?
074        }
075        return null;
076    }
077
078    /**
079     * Dumps object to file stream on binary format.
080     *
081     * @param file Output file stream
082     * @throws IOException if an I/O error occurs.
083     */
084    public final void dump(final DataOutputStream file) throws IOException {
085        file.writeShort(nameIndex);
086        file.writeShort(accessFlags);
087    }
088
089    public int getAccessFlags() {
090        return accessFlags;
091    }
092
093    public int getNameIndex() {
094        return nameIndex;
095    }
096
097    /**
098     * Gets the name of the parameter.
099     *
100     * @param constantPool The pool to query.
101     * @return Constant from the given pool.
102     */
103    public String getParameterName(final ConstantPool constantPool) {
104        if (nameIndex == 0) {
105            return null;
106        }
107        return constantPool.getConstantUtf8(nameIndex).getBytes();
108    }
109
110    public boolean isFinal() {
111        return (accessFlags & Const.ACC_FINAL) != 0;
112    }
113
114    public boolean isMandated() {
115        return (accessFlags & Const.ACC_MANDATED) != 0;
116    }
117
118    public boolean isSynthetic() {
119        return (accessFlags & Const.ACC_SYNTHETIC) != 0;
120    }
121
122    public void setAccessFlags(final int accessFlags) {
123        this.accessFlags = accessFlags;
124    }
125
126    public void setNameIndex(final int nameIndex) {
127        this.nameIndex = nameIndex;
128    }
129}