/*
 * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.tools.java;

import sun.tools.tree.*;
import java.util.Vector;
import java.util.Hashtable;
import java.io.IOException;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;

This class represents a binary member WARNING: The contents of this source file are not part of any supported API. Code that depends on them does so at its own risk: they are subject to change or removal without notice.
/** * This class represents a binary member * * WARNING: The contents of this source file are not part of any * supported API. Code that depends on them does so at its own risk: * they are subject to change or removal without notice. */
public final class BinaryMember extends MemberDefinition { Expression value; BinaryAttribute atts;
Constructor
/** * Constructor */
public BinaryMember(ClassDefinition clazz, int modifiers, Type type, Identifier name, BinaryAttribute atts) { super(0, clazz, modifiers, type, name, null, null); this.atts = atts; // Was it compiled as deprecated? if (getAttribute(idDeprecated) != null) { this.modifiers |= M_DEPRECATED; } // Was it synthesized by the compiler? if (getAttribute(idSynthetic) != null) { this.modifiers |= M_SYNTHETIC; } }
Constructor for an inner class.
/** * Constructor for an inner class. */
public BinaryMember(ClassDefinition innerClass) { super(innerClass); }
Inline allowed (currently only allowed for the constructor of Object).
/** * Inline allowed (currently only allowed for the constructor of Object). */
public boolean isInlineable(Environment env, boolean fromFinal) { // It is possible for 'getSuperClass()' to return null due to error // recovery from cyclic inheritace. Can this cause a problem here? return isConstructor() && (getClassDefinition().getSuperClass() == null); }
Get arguments
/** * Get arguments */
public Vector getArguments() { if (isConstructor() && (getClassDefinition().getSuperClass() == null)) { Vector v = new Vector(); v.addElement(new LocalMember(0, getClassDefinition(), 0, getClassDefinition().getType(), idThis)); return v; } return null; }
Get exceptions
/** * Get exceptions */
public ClassDeclaration[] getExceptions(Environment env) { if ((!isMethod()) || (exp != null)) { return exp; } byte data[] = getAttribute(idExceptions); if (data == null) { return new ClassDeclaration[0]; } try { BinaryConstantPool cpool = ((BinaryClass)getClassDefinition()).getConstants(); DataInputStream in = new DataInputStream(new ByteArrayInputStream(data)); // JVM 4.7.5 Exceptions_attribute.number_of_exceptions int n = in.readUnsignedShort(); exp = new ClassDeclaration[n]; for (int i = 0 ; i < n ; i++) { // JVM 4.7.5 Exceptions_attribute.exception_index_table[] exp[i] = cpool.getDeclaration(env, in.readUnsignedShort()); } return exp; } catch (IOException e) { throw new CompilerError(e); } }
Get documentation
/** * Get documentation */
public String getDocumentation() { if (documentation != null) { return documentation; } byte data[] = getAttribute(idDocumentation); if (data == null) { return null; } try { return documentation = new DataInputStream(new ByteArrayInputStream(data)).readUTF(); } catch (IOException e) { throw new CompilerError(e); } }
Check if constant: Will it inline away to a constant? This override is needed to solve bug 4128266. It is also integral to the solution of 4119776.
/** * Check if constant: Will it inline away to a constant? * This override is needed to solve bug 4128266. It is also * integral to the solution of 4119776. */
private boolean isConstantCache = false; private boolean isConstantCached = false; public boolean isConstant() { if (!isConstantCached) { isConstantCache = isFinal() && isVariable() && getAttribute(idConstantValue) != null; isConstantCached = true; } return isConstantCache; }
Get the value
/** * Get the value */
public Node getValue(Environment env) { if (isMethod()) { return null; } if (!isFinal()) { return null; } if (getValue() != null) { return (Expression)getValue(); } byte data[] = getAttribute(idConstantValue); if (data == null) { return null; } try { BinaryConstantPool cpool = ((BinaryClass)getClassDefinition()).getConstants(); // JVM 4.7.3 ConstantValue.constantvalue_index Object obj = cpool.getValue(new DataInputStream(new ByteArrayInputStream(data)).readUnsignedShort()); switch (getType().getTypeCode()) { case TC_BOOLEAN: setValue(new BooleanExpression(0, ((Number)obj).intValue() != 0)); break; case TC_BYTE: case TC_SHORT: case TC_CHAR: case TC_INT: setValue(new IntExpression(0, ((Number)obj).intValue())); break; case TC_LONG: setValue(new LongExpression(0, ((Number)obj).longValue())); break; case TC_FLOAT: setValue(new FloatExpression(0, ((Number)obj).floatValue())); break; case TC_DOUBLE: setValue(new DoubleExpression(0, ((Number)obj).doubleValue())); break; case TC_CLASS: setValue(new StringExpression(0, (String)cpool.getValue(((Number)obj).intValue()))); break; } return (Expression)getValue(); } catch (IOException e) { throw new CompilerError(e); } }
Get a field attribute
/** * Get a field attribute */
public byte[] getAttribute(Identifier name) { for (BinaryAttribute att = atts ; att != null ; att = att.next) { if (att.name.equals(name)) { return att.data; } } return null; } public boolean deleteAttribute(Identifier name) { BinaryAttribute walker = null, next = null; boolean succeed = false; while (atts.name.equals(name)) { atts = atts.next; succeed = true; } for (walker = atts; walker != null; walker = next) { next = walker.next; if (next != null) { if (next.name.equals(name)) { walker.next = next.next; next = next.next; succeed = true; } } } for (walker = atts; walker != null; walker = walker.next) { if (walker.name.equals(name)) { throw new InternalError("Found attribute " + name); } } return succeed; } /* * Add an attribute to a field */ public void addAttribute(Identifier name, byte data[], Environment env) { this.atts = new BinaryAttribute(name, data, this.atts); // Make sure that the new attribute is in the constant pool ((BinaryClass)(this.clazz)).cpool.indexString(name.toString(), env); } }