001 /* MBEL: The Microsoft Bytecode Engineering Library 002 * Copyright (C) 2003 The University of Arizona 003 * http://www.cs.arizona.edu/mbel/license.html 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018 */ 019 020 021 package edu.arizona.cs.mbel.signature; 022 023 /** This class describes the return type of a method in a method signature 024 * @author Michael Stepp 025 */ 026 public class ReturnTypeSignature extends Signature{ 027 private ParameterInfo paramInfo; 028 // Signature fields 029 private java.util.Vector customMods; // CustomModifierSignatures 030 private TypeSignature type; 031 private byte elementType; 032 // elementType: meaning: 033 // TYPEONLY just Type without BYREF 034 // BYREF BYREF and Type 035 // TYPEDBYREF TYPEDBYREF 036 // VOID VOID 037 038 private ReturnTypeSignature(){ 039 customMods = new java.util.Vector(10); 040 } 041 042 /** Makes a new ReturnTypeSignature object with the given type, possibly by reference 043 * @param typeSig the type of this return value 044 * @param byref true iff this value is returned by reference 045 */ 046 public ReturnTypeSignature(TypeSignature typeSig, boolean byref) throws SignatureException{ 047 this(); 048 type = typeSig; 049 if (type==null) 050 throw new SignatureException("ReturnTypeSignature: Return type is null"); 051 elementType = (byref ? ELEMENT_TYPE_BYREF : ELEMENT_TYPE_TYPEONLY); 052 } 053 054 /** Makes a new ReturnTypeSignature object with the given type code 055 * @param typecode must be one of ELEMENT_TYPE_TYPEDBYREF or ELEMENT_TYPE_VOID 056 */ 057 public ReturnTypeSignature(byte typecode) throws SignatureException{ 058 this(); 059 if (typecode == ELEMENT_TYPE_TYPEDBYREF) 060 elementType = typecode; 061 else if (typecode==ELEMENT_TYPE_VOID) 062 elementType = typecode; 063 else 064 throw new SignatureException("ReturnTypeSignature: Invalid byte code given"); 065 } 066 067 068 /** Factory method to parse a ReturnTypeSignature from a ByteBuffer blob 069 * @param buffer the buffer to read from 070 * @param group a TypeGroup for reconciling tokens to mbel references 071 * @return a ReturnTypeSignature representing the given blob, or null if there was a parse error 072 */ 073 public static ReturnTypeSignature parse(edu.arizona.cs.mbel.ByteBuffer buffer, edu.arizona.cs.mbel.mbel.TypeGroup group){ 074 ReturnTypeSignature blob = new ReturnTypeSignature(); 075 076 int pos = buffer.getPosition(); 077 CustomModifierSignature temp = CustomModifierSignature.parse(buffer, group); 078 while(temp!=null){ 079 blob.customMods.add(temp); 080 pos = buffer.getPosition(); 081 temp = CustomModifierSignature.parse(buffer, group); 082 } 083 buffer.setPosition(pos); 084 085 blob.elementType = ELEMENT_TYPE_TYPEONLY; 086 byte data = buffer.peek(); 087 if (data==ELEMENT_TYPE_TYPEDBYREF){ 088 // TYPEDBYREF 089 blob.elementType = data; 090 buffer.get(); 091 }else if (data==ELEMENT_TYPE_VOID){ 092 // VOID 093 blob.elementType = data; 094 buffer.get(); 095 }else{ 096 if (data==ELEMENT_TYPE_BYREF){ 097 // BYREF Type 098 blob.elementType = data; 099 buffer.get(); 100 } 101 blob.type = TypeSignature.parse(buffer, group); 102 if (blob.type == null) 103 return null; 104 } 105 106 return blob; 107 } 108 109 /** Returns the ParamInfo object of this return type (may be null) 110 */ 111 public ParameterInfo getParameterInfo(){ 112 return paramInfo; 113 } 114 115 /** Sets the ParamInfo object for this return type (may be null) 116 */ 117 public void setParameterInfo(ParameterInfo info){ 118 paramInfo = info; 119 } 120 121 /** Returns the type of returntype this is: 122 * Type: Meaning: 123 * ELEMENT_TYPE_TYPEONLY Return value is given by the TypeSignature 124 * ELEMENT_TYPE_BYREF Return value is given by the TypeSignature, passed by reference 125 * ELEMENT_TYPE_TYPEDBYREF Return value is typed by reference 126 * ELEMENT_TYPE_VOID Void return type 127 */ 128 public int getElementType(){ 129 return elementType; 130 } 131 132 /** Returns the type signature for this return type (may be null) 133 */ 134 public TypeSignature getType(){ 135 return type; 136 } 137 138 /** Getter method for the CustomModifiers applied to this ReturnTypeSignature 139 */ 140 public CustomModifierSignature[] getCustomModifiers(){ 141 CustomModifierSignature[] sigs = new CustomModifierSignature[customMods.size()]; 142 for (int i=0;i<sigs.length;i++) 143 sigs[i] = (CustomModifierSignature)customMods.get(i); 144 145 return sigs; 146 } 147 148 /** Write this signature out to the given buffer in raw binary form 149 * @param buffer the buffer to write to 150 */ 151 public void emit(edu.arizona.cs.mbel.ByteBuffer buffer, edu.arizona.cs.mbel.emit.ClassEmitter emitter){ 152 for (int i=0;i<customMods.size();i++) 153 ((CustomModifierSignature)customMods.get(i)).emit(buffer, emitter); 154 if (elementType == ELEMENT_TYPE_BYREF){ 155 buffer.put(ELEMENT_TYPE_BYREF); 156 type.emit(buffer, emitter); 157 } 158 else if (elementType == ELEMENT_TYPE_TYPEONLY) 159 type.emit(buffer, emitter); 160 else if (elementType == ELEMENT_TYPE_TYPEDBYREF) 161 buffer.put(ELEMENT_TYPE_TYPEDBYREF); 162 else if (elementType == ELEMENT_TYPE_VOID) 163 buffer.put(ELEMENT_TYPE_VOID); 164 } 165 166 /* 167 public void output(){ 168 System.out.print("ReturnTypeSignature["); 169 for (int i=0;i<customMods.size();i++){ 170 ((CustomModifierSignature)customMods.get(i)).output(); 171 System.out.print(','); 172 } 173 174 if (elementType==ELEMENT_TYPE_TYPEONLY){ 175 type.output(); 176 }else if (elementType == ELEMENT_TYPE_BYREF){ 177 System.out.print("BYREF,"); 178 type.output(); 179 }else if (elementType == ELEMENT_TYPE_TYPEDBYREF){ 180 System.out.print("TYPEDBYREF"); 181 }else{ 182 System.out.print("VOID"); 183 } 184 System.out.print("]"); 185 } 186 */ 187 }