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