2014-09-02 08:33:54 +00:00
package de.dhbwstuttgart.syntaxtree ;
2013-10-18 11:33:46 +00:00
2015-09-02 15:11:32 +00:00
import org.apache.commons.bcel6.Constants ;
import org.apache.commons.bcel6.classfile.ConstantPool ;
import org.apache.commons.bcel6.generic.ClassGen ;
import org.apache.commons.bcel6.generic.ConstantPoolGen ;
import org.apache.commons.bcel6.generic.InstructionFactory ;
import org.apache.commons.bcel6.generic.InstructionHandle ;
import org.apache.commons.bcel6.generic.InstructionList ;
import org.apache.commons.bcel6.generic.MethodGen ;
2014-02-19 04:20:54 +00:00
2015-05-27 13:57:15 +00:00
import de.dhbwstuttgart.typeinference.Menge ;
2015-09-02 15:11:32 +00:00
import de.dhbwstuttgart.bytecode.ClassGenerator ;
2015-09-10 14:21:30 +00:00
import de.dhbwstuttgart.bytecode.DHBWConstantPoolGen ;
2015-09-17 18:57:33 +00:00
import de.dhbwstuttgart.bytecode.DHBWInstructionFactory ;
2015-09-23 13:30:35 +00:00
import de.dhbwstuttgart.bytecode.MethodGenerator ;
2014-09-05 09:49:31 +00:00
import de.dhbwstuttgart.parser.JavaClassName ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.misc.DeclId ;
2014-09-05 09:49:31 +00:00
import de.dhbwstuttgart.syntaxtree.modifier.Modifiers ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.statement.Block ;
2015-09-17 18:57:33 +00:00
import de.dhbwstuttgart.syntaxtree.statement.Return ;
2015-06-17 10:03:54 +00:00
import de.dhbwstuttgart.syntaxtree.statement.SuperCall ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.syntaxtree.type.GenericTypeVar ;
import de.dhbwstuttgart.syntaxtree.type.RefType ;
import de.dhbwstuttgart.syntaxtree.type.Type ;
2015-02-25 15:34:29 +00:00
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.ConstraintsSet ;
import de.dhbwstuttgart.typeinference.JavaCodeResult ;
import de.dhbwstuttgart.typeinference.ResultSet ;
2015-11-27 15:10:35 +00:00
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption ;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption ;
2015-02-25 17:29:44 +00:00
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.assumptions.TypeAssumptions ;
2015-09-17 18:57:33 +00:00
import de.dhbwstuttgart.typeinference.exceptions.DebugException ;
2014-09-02 08:33:54 +00:00
import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException ;
2015-02-25 15:34:29 +00:00
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint ;
import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet ;
2015-02-25 17:51:48 +00:00
import de.dhbwstuttgart.syntaxtree.type.Void ;
2014-02-19 04:20:54 +00:00
2014-02-14 16:31:55 +00:00
public class Constructor extends Method {
/ * *
* Parser kann nicht zwischen einem Konstruktor und einer Methode unterscheiden .
* Diese Klasse beherbegt den als Methode geparsten Konstruktor und wandelt sein verhalten zu dem eines Konstruktors ab .
* /
2015-08-26 12:48:51 +00:00
public Constructor ( Method methode , Class parent ) {
2015-02-25 17:29:44 +00:00
super ( methode . get_Method_Name ( ) , methode . getType ( ) , methode . getParameterList ( ) , methode . get_Block ( ) , methode . getGenericDeclarationList ( ) , methode . getOffset ( ) ) ;
2015-06-17 10:03:54 +00:00
//Sicherstellen, dass das erste Statement in der Methode ein SuperCall ist:
if ( this . get_Block ( ) . get_Statement ( ) . size ( ) < 1 | | ! ( this . get_Block ( ) . get_Statement ( ) . firstElement ( ) instanceof SuperCall ) ) {
this . get_Block ( ) . statements . add ( 0 , new SuperCall ( this . get_Block ( ) ) ) ;
2015-08-26 12:48:51 +00:00
this . parserPostProcessing ( parent ) ;
2015-06-17 10:03:54 +00:00
}
2015-02-25 17:29:44 +00:00
}
@Override
public TypeAssumptions createTypeAssumptions ( Class classmember ) {
this . parent = classmember ;
Class parentClass = this . getParentClass ( ) ;
TypeAssumptions ret = new TypeAssumptions ( ) ;
ret . addAssumption ( new ConstructorAssumption ( this , parentClass ) ) ;
return ret ;
}
2015-05-27 13:57:15 +00:00
2015-09-02 15:11:32 +00:00
public void genByteCode ( ClassGenerator cg , InstructionList fieldInitializations ) {
2015-09-10 14:21:30 +00:00
DHBWConstantPoolGen _cp = cg . getConstantPool ( ) ;
2015-06-16 12:58:27 +00:00
InstructionList il = new InstructionList ( ) ; //sollte nicht new sein sondern aus Block kommen
2015-05-27 13:57:15 +00:00
Class parentClass = this . getParentClass ( ) ;
2015-12-08 12:34:16 +00:00
MethodGenerator method = new MethodGenerator ( Constants . ACC_PUBLIC , this . getType ( ) . getBytecodeType ( cg , null ) , this . parameterlist . getBytecodeTypeList ( cg , null ) , this . parameterlist . getParameterNameArray ( ) , " <init> " , parentClass . name , il , _cp ) ;
2015-06-17 10:03:54 +00:00
2015-09-23 13:30:35 +00:00
//FieldInitializations an Block anfügen
2015-06-18 09:17:42 +00:00
Block block = this . get_Block ( ) ;
2015-09-02 15:11:32 +00:00
if ( block . statements . firstElement ( ) instanceof SuperCall ) {
block . statements . insertElementAt ( new BytecodeInstructionBlock ( fieldInitializations ) , 1 ) ;
2015-09-17 18:57:33 +00:00
} else {
throw new DebugException ( " Fehlender SuperCall im Konstruktor " ) ;
2015-09-02 15:11:32 +00:00
}
2015-06-17 10:03:54 +00:00
2015-09-23 13:30:35 +00:00
//method.setMaxStack(); //Die Stack Größe automatisch berechnen lassen (erst nach dem alle Instructions angehängt wurden)
2015-06-17 10:03:54 +00:00
2015-12-05 14:15:28 +00:00
cg . addMethod ( method . createMethod ( cg , getParameterList ( ) , this . getType ( ) , get_Block ( ) , null ) ) ;
2015-05-27 13:57:15 +00:00
}
2015-09-02 15:11:32 +00:00
/ * *
* Mit dieser Hilfsklasse kann eine beliebige InstructionList in eine vorhandenen Block als Statement eingefügt werden .
* Wird für Bytecodegenerierung benötigt .
* /
private class BytecodeInstructionBlock extends Block {
InstructionList il ;
BytecodeInstructionBlock ( InstructionList toInsert ) {
il = toInsert ;
}
@Override
2015-11-27 15:10:35 +00:00
public InstructionList genByteCode ( ClassGenerator cg , TypeinferenceResultSet rs ) {
2015-09-02 15:11:32 +00:00
return il ;
}
}
@Override
2016-03-20 17:55:36 +00:00
public void genByteCode ( ClassGenerator cg , Class classObj ) {
2015-09-02 15:11:32 +00:00
this . genByteCode ( cg , new InstructionList ( ) ) ;
}
2015-06-16 09:55:15 +00:00
// super statement muss drin sein
// stmt genByteCode + im block genByteCode implementieren & dann Hierarchie ausprobieren
// de.dhbw.systanxtree.stmts supercall
2015-06-16 15:44:27 +00:00
// Aufrufhierarchie: Class->Felder->Konstruktor->Methode innerhalb Konstruktor->Block->Statements (in diesem Fall nur super())->hier wird bytecode f<> r superaufruf generiert
2015-06-16 09:55:15 +00:00
2015-05-27 13:57:15 +00:00
2015-02-25 17:29:44 +00:00
@Override
public void parserPostProcessing ( SyntaxTreeNode parent ) {
2015-06-16 20:08:17 +00:00
super . parserPostProcessing ( parent ) ;
2015-02-25 17:29:44 +00:00
if ( this . parameterlist ! = null ) {
for ( FormalParameter fp : this . parameterlist ) {
fp . parserPostProcessing ( this ) ;
}
}
for ( GenericTypeVar gtv : this . getGenericParameter ( ) ) {
gtv . parserPostProcessing ( this ) ;
}
}
2015-06-16 09:55:15 +00:00
2015-02-25 17:29:44 +00:00
@Override
public ConstraintsSet TYPE ( TypeAssumptions ass ) {
2015-02-25 17:51:48 +00:00
//super.setType(this.getParentClass().getType());
super . setType ( new Void ( this , 0 ) ) ;
2015-02-25 17:29:44 +00:00
return super . TYPE ( ass ) ;
}
@Override
public void setType ( Type t ) {
2015-02-26 14:50:23 +00:00
super . setType ( new Void ( this , this . getOffset ( ) ) ) ;
//throw new TypeinferenceException("Einem Konstruktor kann kein Typ zugewiesen werden", this);
2015-02-25 17:29:44 +00:00
//this.methode.setType(t);
2015-02-25 15:34:29 +00:00
}
2015-06-16 09:55:15 +00:00
/ * public Constructor ( Method methode ) {
2014-03-09 11:10:03 +00:00
super ( methode . getOffset ( ) ) ;
2014-02-14 16:31:55 +00:00
this . methode = methode ;
2015-04-22 19:40:22 +00:00
this . setDeclIdMenge ( methode . getDeclIdMenge ( ) ) ;
2014-03-20 10:35:57 +00:00
this . methode . setType ( this . methode . getParentClass ( ) . getType ( ) ) ;
2015-06-16 09:55:15 +00:00
} * /
2014-02-19 04:20:54 +00:00
@Override
2014-09-02 16:49:19 +00:00
public JavaClassName getTypeName ( ) {
2014-02-19 04:20:54 +00:00
2014-02-19 16:32:43 +00:00
return this . getType ( ) . getName ( ) ;
2014-02-19 04:20:54 +00:00
}
2015-08-26 12:48:51 +00:00
2013-10-18 11:33:46 +00:00
}
2014-03-27 15:43:07 +00:00
/ *
// ino.class.Constructor.23267.declaration
public class Constructor_Backup extends Method
// ino.end
// ino.class.Constructor.23267.body
{
// ino.method.Constructor.23271.definition
public Constructor_Backup ( )
// ino.end
// ino.method.Constructor.23271.body
{
this . setParameterList ( null ) ;
// #JB# 04.06.2005
// ###########################################################
DeclId decl = new DeclId ( ) ;
decl . set_Name ( " <init> " ) ;
this . set_DeclId ( decl ) ;
// ###########################################################
}
// ino.end
// ino.method.get_codegen_Param_Type.23274.definition
2015-04-22 19:40:22 +00:00
public String get_codegen_Param_Type ( Menge paralist )
2014-03-27 15:43:07 +00:00
// ino.end
// ino.method.get_codegen_Param_Type.23274.body
{
String ret = new String ( ) ;
if ( this . getParameterList ( ) = = null )
{
ret + = " () " ;
}
else
{
ret + = this . getParameterList ( ) . get_codegen_ParameterList ( paralist ) ;
}
ret + = " V " ;
return ret ;
}
// ino.end
// ino.method.codegen.23277.definition
2015-04-22 19:40:22 +00:00
public void codegen ( ClassFile classfile , Menge paralist )
2014-03-27 15:43:07 +00:00
throws JVMCodeException
// ino.end
// ino.method.codegen.23277.body
{
classfile . set_constructor_founded ( true ) ;
classfile . add_method ( " <init> " , this . get_codegen_Param_Type ( paralist ) , this . getParameterList ( ) , null , get_Block ( ) , declid . firstElement ( ) . get_access_flags ( ) , paralist , false ) ;
}
// ino.end
}
* /