JavaCompilerCore/src/de/dhbwstuttgart/bytecode/SignatureInfo.java

277 lines
9.1 KiB
Java
Executable File

// ino.module.SignatureInfo.8550.package
package de.dhbwstuttgart.bytecode;
// ino.end
// ino.module.SignatureInfo.8550.import
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Vector;
import de.dhbwstuttgart.logger.Logger;
// ino.end
import de.dhbwstuttgart.myexception.JVMCodeException;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.misc.UsedId;
import de.dhbwstuttgart.syntaxtree.type.BoundedGenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.Type;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
// ino.class.SignatureInfo.22968.description type=javadoc
/**
* Generiert die Attribute eines Fields, einer Methode oder einer Klasse/Interface
* zur Integration der Signatur (Generics).
* @author SCJU
*/
// ino.end
// ino.class.SignatureInfo.22968.declaration
public class SignatureInfo extends Attribute
// ino.end
// ino.class.SignatureInfo.22968.body
{
// ino.attribute.signatureID.22972.decldescription type=line
// UTF-8 Konstante mit der Signatur selbst
// ino.end
// ino.attribute.signatureID.22972.declaration
private short signatureID = 0;
// ino.end
// ino.attribute.codegenlog.22975.decldescription type=line
// Logger fuer Code-Gen
// ino.end
// ino.attribute.codegenlog.22975.declaration
protected static Logger codegenlog = Logger.getLogger("codegen");
// ino.end
public SignatureInfo(short sid) {
signatureID = sid;
}
// ino.method.SignatureInfo.22978.defdescription type=javadoc
/**
* Konstruktor fuer die Signatur einer Klasse bzw. eines Interfaces.
*/
// ino.end
// ino.method.SignatureInfo.22978.definition
public SignatureInfo(Vector<Type> vec, UsedId superclass, Vector<UsedId> superIf, ClassFile cf)
// ino.end
// ino.method.SignatureInfo.22978.body
{
StringBuffer sb = new StringBuffer();
sb.append("<");
set_attribute_name_index(cf.getSignatureID());
// Parameterliste verarbeiten, falls vorhanden
Type type;
for (int i=0; i<vec.size(); i++) {
type = vec.elementAt(i);
if (type instanceof BoundedGenericTypeVar)
sb.append(((BoundedGenericTypeVar)type).getSignatureDefinition());
else if (type instanceof GenericTypeVar)
sb.append(type.getName()+ ":"+ JVMCode.get_codegen_Type( "Object", null));
}
sb.append(">");
if (superclass == null && (superIf == null || superIf.size() == 0)) {
// Falls keine Superclassen oder Interfaces angegeben wurden,
// wird per Definition wird nochmals "Ljava/lang/Object;" angehaengt
sb.append(JVMCode.get_codegen_Type("Object", null));
} else {
if (superclass != null) sb.append(superclass.getSignatureUsedId());
if (superIf != null && superIf.size() > 0) {
for (int i=0; i<superIf.size(); i++) {
sb.append(superIf.elementAt(i).getSignatureUsedId());
}
}
}
set_attribute_name_index(cf.getSignatureID());
signatureID = (short) cf.add_CONSTANT_Utf8_info(sb.toString());
codegenlog.debug("Signatur fuer Klasse erstellt: " + sb.toString());
}
// ino.end
// ino.method.SignatureInfo.22981.defdescription type=javadoc
/**
* Konstruktor fuer eine Signatur einer Instanzvariable.
* @throws JVMCodeException
*/
// ino.end
// ino.method.SignatureInfo.22981.definition
public SignatureInfo(Type type, ClassFile cf)
throws JVMCodeException
// ino.end
// ino.method.SignatureInfo.22981.body
{
String cmplType = "";
if (type instanceof RefType) {
RefType rf = (RefType) type;
if (rf.get_ParaList().size() == 0)
throw new JVMCodeException("Signatur kann nicht generiert werden - keine Typinformationen!");
cmplType = rf.getSignatureType(null);
} else if (type instanceof GenericTypeVar || type instanceof BoundedGenericTypeVar) {
cmplType = ((GenericTypeVar)type).getSignatureType(null);
} else {
throw new JVMCodeException("Signatur kann fuer unbekannten Typ " + type.getClass().getName()
+ " nicht generiert werden!");
}
set_attribute_name_index(cf.getSignatureID());
signatureID = (short) cf.add_CONSTANT_Utf8_info(cmplType);
codegenlog.debug("Signatur fuer Variable erstellt: " + cmplType);
}
// ino.end
// ino.method.SignatureInfo.22984.defdescription type=javadoc
/**
* Konstruktor fuer eine Methodensignatur.
* @throws JVMCodeException
*/
// ino.end
// ino.method.SignatureInfo.22984.definition
public SignatureInfo(ParameterList param, Type type, ClassFile cf)
throws JVMCodeException
// ino.end
// ino.method.SignatureInfo.22984.body
{
if (param == null && type == null)
throw new JVMCodeException("Signatur kann nicht generiert werden - keine Typinformationen!");
StringBuffer sig = new StringBuffer();
// Falls RueckgabeWert vom Typ BoundedGenericTypeVar ist, muss vorher schon die
// Definition erfolgen!
if (type instanceof BoundedGenericTypeVar) {
sig.append("<");
sig.append(((BoundedGenericTypeVar)type).getSignatureDefinition());
sig.append(">");
}
sig.append("(");
// Parameterliste verarbeiten, falls vorhanden
if (param != null) {
for (int i=0; i<param.getParameterCount(); i++) {
sig.append(param.getParameterAt(i).getType().getSignatureType(null));
}
}
// RueckgabeTyp
sig.append(")");
sig.append(type.getSignatureType(null));
set_attribute_name_index(cf.getSignatureID());
signatureID = (short) cf.add_CONSTANT_Utf8_info(sig.toString());
codegenlog.debug("Signatur fuer Methode erstellt: " + sig.toString());
}
// ino.end
// ino.method.codegen.22987.definition
public void codegen(ClassFile classfile, OutputStream f)
throws JVMCodeException, IOException
// ino.end
// ino.method.codegen.22987.body
{
// Verweis auf Signature
classfile.writeShort(f, get_attribute_name_index());
// Laenge des Verweises auf Konstantenpool, per Definition 2
classfile.writeInt(f, get_attributes_length());
// Verweis auf den Konstantenpool
classfile.writeShort(f, signatureID);
}
// ino.end
// ino.method.needsSignature.22990.defdescription type=javadoc
/**
* Gibt zurueck, ob eine Signaturdefinition fuer den Typ erforderlich ist.
*/
// ino.end
// ino.method.needsSignature.22990.definition
public static boolean needsSignature(Type typ)
// ino.end
// ino.method.needsSignature.22990.body
{
if (typ == null) return false;
// Fuer GenericTypeVars wird in jedem Fall eine Signatur benoetigt
if (typ instanceof GenericTypeVar || typ instanceof BoundedGenericTypeVar) return true;
// Falls nicht RefType, brauchen wir keine Signatur
if (!(typ instanceof RefType)) return false;
RefType rf = (RefType) typ;
// Die Definition eines Generics ist zwingend erforderlich.
if (rf.get_ParaList() == null || rf.get_ParaList().size() == 0) return false;
return true;
}
// ino.end
// ino.method.needsSignature.22993.defdescription type=javadoc
/**
* Gibt zurueck, ob eine Signaturdefinition fuer die Methode erforderlich ist.
*/
// ino.end
// ino.method.needsSignature.22993.definition
public static boolean needsSignature(ParameterList param, Type type)
// ino.end
// ino.method.needsSignature.22993.body
{
// Fuer Rueckgabetyp erforderlich???
if (needsSignature(type)) return true;
// Parameter testen
boolean needed = false;
if (param == null) return false;
for (int i=0; (i<param.formalparameter.size()) && (!needed); i++) {
needed = needsSignature(param.formalparameter.elementAt(i).getType());
if (needed) return true;
}
return needed;
}
// ino.end
// ino.method.get_attributes_length.22996.definition
public int get_attributes_length()
// ino.end
// ino.method.get_attributes_length.22996.body
{
// Laenge des Verweises auf den Konstantenpool,
// per Definition 2.
return 2;
}
// ino.end
// @Override
// public void codegen(ClassFile classfile, OutputStream f)
// throws JVMCodeException, IOException {
// throw new NotImplementedException();
// }
}
// ino.end