JavaPatternMatching/src/mycompiler/myclass/Method.java

707 lines
23 KiB
Java
Raw Normal View History

2013-10-18 11:33:46 +00:00
// ino.module.Method.8564.package
package mycompiler.myclass;
// ino.end
// ino.module.Method.8564.import
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;
2013-10-18 11:33:46 +00:00
import mycompiler.IItemWithOffset;
2014-02-12 01:12:12 +00:00
import mycompiler.SyntaxTreeNode;
2013-10-18 11:33:46 +00:00
import mycompiler.mybytecode.ClassFile;
import mycompiler.MyCompiler;
import mycompiler.myexception.JVMCodeException;
import mycompiler.myexception.SCMethodException;
import mycompiler.myexception.SCStatementException;
import mycompiler.mymodifier.Modifiers;
import mycompiler.mystatement.Block;
import mycompiler.mystatement.Return;
import mycompiler.mytype.GenericTypeVar;
import mycompiler.mytype.RefType;
import mycompiler.mytype.Type;
import mycompiler.mytype.TypePlaceholder;
import mycompiler.mytypereconstruction.replacementlistener.CReplaceTypeEvent;
import mycompiler.mytypereconstruction.replacementlistener.ITypeReplacementListener;
import mycompiler.mytypereconstruction.set.CTypeAssumptionSet;
import mycompiler.mytypereconstruction.typeassumption.CInstVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CLocalVarTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CMethodTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CParaTypeAssumption;
import mycompiler.mytypereconstruction.typeassumption.CTypeAssumption;
import org.apache.log4j.Logger;
import typinferenz.JavaCodeResult;
import typinferenz.SingleConstraint;
import typinferenz.ConstraintsSet;
import typinferenz.ResultSet;
import typinferenz.TypeInsertable;
import typinferenz.assumptions.MethodAssumption;
2014-02-19 16:32:43 +00:00
import typinferenz.assumptions.ParameterAssumption;
import typinferenz.assumptions.TypeAssumptions;
2013-10-18 11:33:46 +00:00
// ino.class.Method.23482.declaration
/**
* Stellt eine Methode dar.
* Problem: Parser kann nicht zwischen Methode und Konstruktor unterscheiden. Daher kann diese Klasse beides sein. Dies wird mit dem ParserPostProcessing behoben.
* @author janulrich
*
*/
public class Method extends Field implements IItemWithOffset, TypeInsertable
2013-10-18 11:33:46 +00:00
// ino.end
// ino.class.Method.23482.body
{
// ino.attribute.block.23488.declaration
private Block block;
// ino.end
// ino.attribute.parameterlist.23491.declaration
public ParameterList parameterlist = new ParameterList();
2013-10-18 11:33:46 +00:00
// ino.end
// ino.attribute.exceptionlist.23494.declaration
private ExceptionList exceptionlist;
// ino.end
// ino.attribute.returntype.23497.declaration
private Type returntype;
// ino.end
// ino.attribute.genericMethodParameters.23500.decldescription type=javadoc
/**
* HOTI 4.5.06
* Dieser Vektor beinhaltet alle Generischen Typen und v.a. die
* F-Bounded-Generics, die die Methode besitzt
* size()==0, falls es keine gibt
*/
// ino.end
// ino.attribute.genericMethodParameters.23500.declaration
private Vector<GenericTypeVar> genericMethodParameters=new Vector<GenericTypeVar>();
// ino.end
// ino.attribute.overloadedID.23503.declaration
private int overloadedID;
// ino.end
// ino.attribute.isAbstract.23506.declaration
private boolean isAbstract = false;
// ino.end
// ino.attribute.types_in_parameterlist.23509.declaration
private Vector<String> types_in_parameterlist = new Vector<String>();
// ino.end
// ino.attribute.m_LineNumber.23512.declaration
private int m_LineNumber = MyCompiler.NO_LINENUMBER;
// ino.end
private int m_Offset = -1; //hinzugef<65>gt hoth: 07.04.2006
// ino.attribute.inferencelog.23515.declaration
protected static Logger inferencelog = Logger.getLogger("inference");
// ino.end
// ino.attribute.parserlog.23518.declaration
protected static Logger parserlog = Logger.getLogger("parser");
// ino.end
public Method(int offset){
super(offset);
}
2013-10-18 11:33:46 +00:00
// ino.method.setGenericMethodParameters.23521.definition
public void setGenericMethodParameters(Vector<GenericTypeVar> genericMethodParameters)
// ino.end
// ino.method.setGenericMethodParameters.23521.body
{
this.genericMethodParameters=genericMethodParameters;
}
// ino.end
// ino.method.getGenericMethodParameters.23524.definition
public Vector<GenericTypeVar> getGenericMethodParameters()
// ino.end
// ino.method.getGenericMethodParameters.23524.body
{
return(genericMethodParameters);
}
// ino.end
// ino.method.sc_init_parameterlist.23530.definition
public void sc_init_parameterlist(boolean ext)
// ino.end
// ino.method.sc_init_parameterlist.23530.body
{
DeclId hilf=null;
Vector<FormalParameter> list;
FormalParameter para;
String typeofpara;
int i=1;
if(this.getParameterList()!=null) //es gibt Parameter, dann:
{
hilf=declid.elementAt(0);
if(ext)
parserlog.debug("Semantik-Check hat in Methode "+hilf.get_Name()+" bergabewerte gefunden:");
list=this.getParameterList().sc_get_Formalparalist(); //Vector Formalparalist aus FormalParameterList wird zwischen gesichert
for(Enumeration<FormalParameter> el2=list.elements(); el2.hasMoreElements();)
{
para=el2.nextElement();
typeofpara=para.getTypeName();
if(ext)
parserlog.debug(" "+i+". Parameter hat Typ "+typeofpara);
types_in_parameterlist.addElement(typeofpara); //Typ der Parameter werden im Vector abgelegt
i++;
}
}
else //keine Parameter vorhanden:
{
if(ext)
{
hilf=declid.elementAt(0);
parserlog.debug("Semantik-Check hat in Methode "+hilf.get_Name()+" keine bergabewerte gefunden.");
}
}
if(ext)
{
parserlog.debug("Semantik-Check hat in Methode "+hilf.get_Name()+" "+ types_in_parameterlist.size()+" bergabeparameter gefunden.");
parserlog.debug(" namentlich: "+types_in_parameterlist.toString());
}
}
// ino.end
// ino.method.getTypeName.23533.defdescription type=line
// Eine der beiden Funktionen ist ueberflssig. Wer sich daran strt kann die
// get_ReturnType() auf eigene Gefahr lschen.
// ino.end
// ino.method.getTypeName.23533.definition
public String getTypeName()
// ino.end
// ino.method.getTypeName.23533.body
{
2014-02-19 16:32:43 +00:00
if( this.getType() == null )
2013-10-18 11:33:46 +00:00
return null;
else
2014-02-19 16:32:43 +00:00
return this.getType().getName();
2013-10-18 11:33:46 +00:00
}
// ino.end
// ino.method.get_Block.23536.definition
public Block get_Block()
// ino.end
// ino.method.get_Block.23536.body
{
return block;
}
// ino.end
// ino.method.setReturnType.23539.defdescription type=javadoc
/**
* <br/>Author: Jrg Buerle
* @param type
*/
// ino.end
// ino.method.setReturnType.23539.definition
2014-02-19 16:32:43 +00:00
private void setReturnType(Type type)
2013-10-18 11:33:46 +00:00
// ino.end
// ino.method.setReturnType.23539.body
{
if(this.returntype instanceof TypePlaceholder){
((TypePlaceholder)this.returntype).removeReplacementListener(this);
}
if(type instanceof TypePlaceholder){
((TypePlaceholder)type).addReplacementListener(this);
}
// this.returntype = type; //auskommentiert von Andreas Stadelmeier (a10023)
this.returntype = type;
}
// ino.end
// ino.method.set_Block.23542.definition
public void set_Block( Block blo)
// ino.end
// ino.method.set_Block.23542.body
{
if(blo.getType() == null)blo.setType(this.returntype);
2013-10-18 11:33:46 +00:00
this.block = blo;
}
// ino.end
// ino.method.set_Modifiers.23545.definition
public void set_Modifiers(Modifiers modif)
// ino.end
// ino.method.set_Modifiers.23545.body
{
declid.firstElement().set_Modifiers(modif);
// this.modi = modif;
}
// ino.end
// ino.method.set_ExceptionList.23548.definition
public void set_ExceptionList(ExceptionList exlist)
// ino.end
// ino.method.set_ExceptionList.23548.body
{
this.exceptionlist = exlist;
}
// ino.end
// ino.method.setParameterList.23551.definition
public void setParameterList( ParameterList paralist )
// ino.end
// ino.method.setParameterList.23551.body
{
this.parameterlist = paralist;
}
// ino.end
// ino.method.getParameterList.23554.definition
public ParameterList getParameterList( )
// ino.end
// ino.method.getParameterList.23554.body
{
// otth: gibt die Parameterliste zurueck
return this.parameterlist;
}
// ino.end
// ino.method.getParameterCount.23557.defdescription type=javadoc
/**
* Author: Jrg Buerle<br/>
* @return Die Anzahl der Methoden-Paramater
*/
// ino.end
// ino.method.getParameterCount.23557.definition
public int getParameterCount()
// ino.end
// ino.method.getParameterCount.23557.body
{
if(this.getParameterList() == null)
return 0;
else
return this.getParameterList().getParameterCount();
}
// ino.end
// ino.method.get_ExceptionList.23560.definition
public ExceptionList get_ExceptionList()
// ino.end
// ino.method.get_ExceptionList.23560.body
{
// otth: gibt die Exceptionliste zurueck
return this.exceptionlist;
}
// ino.end
// ino.method.getOverloadedID.23563.definition
public int getOverloadedID()
// ino.end
// ino.method.getOverloadedID.23563.body
{
return(overloadedID);
}
// ino.end
// ino.method.setOverloadedID.23566.definition
public void setOverloadedID(int overloadedID)
// ino.end
// ino.method.setOverloadedID.23566.body
{
this.overloadedID=overloadedID;
}
// ino.end
2014-02-19 16:32:43 +00:00
2013-10-18 11:33:46 +00:00
// ino.method.get_codegen_Param_Type.23572.definition
public String get_codegen_Param_Type(Vector paralist)
// ino.end
// ino.method.get_codegen_Param_Type.23572.body
{
String ret = new String();
if(this.getParameterList() == null)
{
ret += "()";
}
else
{
ret += this.getParameterList().get_codegen_ParameterList(paralist);
}
2014-02-19 16:32:43 +00:00
if(this.getType() == null)
2013-10-18 11:33:46 +00:00
{
ret += "V";
}
else
{
2014-02-19 16:32:43 +00:00
ret += this.getType().get_codegen_Type(paralist);
2013-10-18 11:33:46 +00:00
}
return ret;
}
// ino.end
// ino.method.get_Method_Name.23575.definition
public String get_Method_Name()
// ino.end
// ino.method.get_Method_Name.23575.body
{
DeclId hilf=declid.elementAt(0);
return hilf.get_Name();
}
// ino.end
// ino.method.get_Type_Paralist.23578.definition
public Vector get_Type_Paralist()
// ino.end
// ino.method.get_Type_Paralist.23578.body
{
return types_in_parameterlist;
}
// ino.end
// ino.method.codegen.23581.definition
public void codegen(ClassFile classfile, Vector paralist)
throws JVMCodeException
// ino.end
// ino.method.codegen.23581.body
{
2014-02-19 16:32:43 +00:00
classfile.add_method(declid.firstElement().get_Name(), this.get_codegen_Param_Type(paralist), this.getParameterList(), this.getType(), block, declid.firstElement().get_access_flags(), paralist, isAbstract);
2013-10-18 11:33:46 +00:00
}
// ino.end
// ino.method.getLineNumber.23584.definition
public int getLineNumber()
// ino.end
// ino.method.getLineNumber.23584.body
{
return m_LineNumber;
}
// ino.end
// ino.method.setLineNumber.23587.definition
public void setLineNumber(int lineNumber)
// ino.end
// ino.method.setLineNumber.23587.body
{
m_LineNumber = lineNumber;
}
// ino.end
// ino.method.getOffset.23590.defdescription type=line
// hinzugef<65>gt hoth: 07.04.2006
// ino.end
// ino.method.getOffset.23590.definition
public int getOffset()
// ino.end
// ino.method.getOffset.23590.body
{
return m_Offset;
}
// ino.end
// ino.method.getVariableLength.23593.definition
public int getVariableLength()
// ino.end
// ino.method.getVariableLength.23593.body
{
return get_Method_Name().length();
}
// ino.end
// ino.method.setOffset.23596.defdescription type=line
// hinzugef<65>gt hoth: 07.04.2006
// ino.end
// ino.method.setOffset.23596.definition
public void setOffset(int Offset)
// ino.end
// ino.method.setOffset.23596.body
{
m_Offset = Offset;
}
// ino.end
// ino.method.replaceType.23599.defdescription type=javadoc
/**
* <br>Author: Jrg Buerle
* @param e
*/
// ino.end
// ino.method.replaceType.23599.definition
public void replaceType(CReplaceTypeEvent e)
// ino.end
// ino.method.replaceType.23599.body
{
inferencelog.debug("Ersetze Typ in Method \""+this.get_Method_Name()+"()\"\n");
if(returntype instanceof TypePlaceholder){
((TypePlaceholder)returntype).removeReplacementListener(this);
}
this.setReturnType(e.getNewType());
}
// ino.end
// ino.method.getTypeLineNumber.23602.defdescription type=javadoc
/**
* <br>Author: Jrg Buerle
* @return
*/
// ino.end
// ino.method.getTypeLineNumber.23602.definition
public int getTypeLineNumber()
// ino.end
// ino.method.getTypeLineNumber.23602.body
{
return this.getLineNumber();
}
// ino.end
// ino.method.toString.23605.defdescription type=javadoc
/**
* <br/>Author: Martin Pl<EFBFBD>micke
* @return
*/
// ino.end
// ino.method.toString.23605.definition
public String toString()
// ino.end
// ino.method.toString.23605.body
{
2014-02-19 16:32:43 +00:00
return this.getType() + " " + block.toString();
2013-10-18 11:33:46 +00:00
}
// ino.end
// ino.method.setAbstract.23608.defdescription type=javadoc
/**
* Legt fuer die ByteCodeGen fest, ob Bytecode
* innerhalb der Methode generiert wird.
*/
// ino.end
// ino.method.setAbstract.23608.definition
public void setAbstract(boolean b)
// ino.end
// ino.method.setAbstract.23608.body
{
isAbstract = b;
}
// ino.end
// ino.method.isAbstract.23611.defdescription type=javadoc
/**
* Gibt zurueck, ob ByteCode innerhabl der Methode
* generiert wird.
*/
// ino.end
// ino.method.isAbstract.23611.definition
public boolean isAbstract()
// ino.end
// ino.method.isAbstract.23611.body
{
return isAbstract;
}
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.23614.definition
public void wandleRefTypeAttributes2GenericAttributes(Vector<Type> paralist)
// ino.end
// ino.method.wandleRefTypeAttributes2GenericAttributes.23614.body
{
// Zuerst Returntype untersuchen
2014-02-19 16:32:43 +00:00
Type returnType=getType();
2013-10-18 11:33:46 +00:00
GenericTypeVar pendantReturnType=ClassHelper.findGenericType(returnType, paralist,genericMethodParameters);
if(pendantReturnType!=null){ //Wenn generisch, dann modifizieren
setReturnType(pendantReturnType);
}
// Dann parameterlist untersuchen
for(int par=0;par<getParameterCount();par++){
FormalParameter fp=parameterlist.formalparameter.get(par);
Type fpType=fp.getType();
// Nur wenn es sich um ein RefType-Field handelt
GenericTypeVar pendantPara=ClassHelper.findGenericType(fpType,paralist,genericMethodParameters);
if(pendantPara!=null){ //Wenn generisch, dann modifizieren
fp.setType(pendantPara);
}
}
// Zuletzt alle Lokalen Variablendeklarationen durchgehen
if(block!=null){
block.wandleRefTypeAttributes2GenericAttributes(paralist,genericMethodParameters);
}
}
// ino.end
// ino.method.set_Method_Name.23617.definition
public void set_Method_Name(String string)
// ino.end
// ino.method.set_Method_Name.23617.body
{
declid.set(0,new DeclId(string));
}
// ino.end
2014-02-19 04:20:54 +00:00
2013-10-18 11:33:46 +00:00
public ConstraintsSet TYPE(TypeAssumptions ass) {
ConstraintsSet ret = new ConstraintsSet();
2014-02-19 16:32:43 +00:00
TypeAssumptions localAss = new TypeAssumptions();
localAss.add(ass); //Die globalen Assumptions anh<6E>ngen
//Die Parameter zu den Assumptions hinzuf<75>gen:
if(this.parameterlist!=null)for(FormalParameter param : this.parameterlist){
localAss.addParameterAssumption(new ParameterAssumption(param));
}
ret.add(this.block.TYPEStmt(localAss));
2013-10-18 11:33:46 +00:00
//eine Verkn<6B>pfung mit der Type Assumption aus dem Assumption Set und dem ermittelten Typ der Methode:
2014-02-19 04:20:54 +00:00
ret.add(new SingleConstraint(this.block.getType(), this.returntype));
2013-10-18 11:33:46 +00:00
return ret;
}
/**
* @author Andreas Stadelmeier, a10023
* @return die TypInformationen der Statements dieser Methode.
*/
public String getTypeInformation(){
if(this.parameterlist!=null)return "Methode "+this.get_Name()+ " Parameter: "+this.parameterlist.getTypeInformation()+", Block: "+this.block.getTypeInformation();
2014-02-19 16:32:43 +00:00
return "Methode "+this.get_Name()+" : "+this.getType()+", Block: "+this.block.getTypeInformation();
2013-10-18 11:33:46 +00:00
}
@Override
public JavaCodeResult printJavaCode(ResultSet resultSet) {
JavaCodeResult ret = new JavaCodeResult();
2014-02-19 16:32:43 +00:00
ret.attach(this.getType().printJavaCode(resultSet)).attach(" ").attach(this.get_Method_Name()).attach("()\n"); //TODO: hier m<>ssen auch noch die Parameter ausgegeben werden!
2013-10-18 11:33:46 +00:00
ret.attach(this.block.printJavaCode(resultSet));
return ret;
}
@Override
public TypeAssumptions createTypeAssumptions(Class classmember) {
Class parentClass = this.getParentClass();
TypeAssumptions ret = new TypeAssumptions();
ret.addMethodAssumption(new MethodAssumption(this, parentClass));
return ret;
/*
2013-10-18 11:33:46 +00:00
TypeAssumptions assumptions = new TypeAssumptions();
this.assumedType = null;
2014-02-19 16:32:43 +00:00
//if((this.get_Method_Name().equals(classmember.getName()) || this.get_Method_Name().equals("<init>")) && ((this.getType().equals(new mycompiler.mytype.Void(0))) || this.getType() instanceof TypePlaceholder)){
2013-10-18 11:33:46 +00:00
if((this.get_Method_Name().equals(classmember.getName()) || this.get_Method_Name().equals("<init>"))) {
this.set_Method_Name("<init>");
this.assumedType = new RefType(classmember.getName(),0);
this.setReturnType(this.assumedType);
this.assumedType = new RefType("void",0);
//Return constructorReturnStatement = new Return(0,0);
//constructorReturnStatement.retexpr =
//this.block.statements.add(constructorReturnStatement);
}
//hoth: 06.04.2006
//durchlaufe Block und suche nach Objektvariablen fuer Offset-Markierung
Iterator<CTypeAssumption> fieldVarIterator = assumptions.iterator();
while (fieldVarIterator.hasNext())
{
//Wenn ObjektVariable
CTypeAssumption dieAssum = fieldVarIterator.next();
if(dieAssum instanceof CInstVarTypeAssumption)
{
Class.isFirstLocalVarDecl=false;
if(this.get_Block() != null)
this.get_Block().addOffsetsToAssumption(dieAssum,dieAssum.getIdentifier(),true);
}
}
//methodList.addElement(method);
//F<>r V_fields_methods:
2014-02-19 16:32:43 +00:00
CMethodTypeAssumption methodAssum = new CMethodTypeAssumption(classmember.getType(), this.get_Method_Name(), this.getType(), this.getParameterCount(),this.getLineNumber(),this.getOffset(),new Vector<Integer>(),this.getGenericMethodParameters()); // Typannahme bauen...
2013-10-18 11:33:46 +00:00
//Methode in V_Fields_methods ablegen
//Dabei wird die OverloadedMethodID ermittelt !!
//=> Method setzenuct
assumptions.add(methodAssum);
this.setOverloadedID(methodAssum.getHashSetKey().getOverloadedMethodID());
//F<>r die V_i:
CTypeAssumptionSet localAssum = new CTypeAssumptionSet();
//Bauen...
ParameterList parameterList = this.getParameterList();
if(parameterList!=null){
for(int i=0; i<parameterList.sc_get_Formalparalist().size(); i++){
FormalParameter para = parameterList.sc_get_Formalparalist().elementAt(i);
// F<>r V_fields_methods:
CParaTypeAssumption paraAssum = new CParaTypeAssumption(classmember.getName(), this.get_Method_Name(), this.getParameterCount(), this.getOverloadedID(),para.get_Name(), para.getType(), para.getLineNumber(),para.getOffset(),new Vector<Integer>());
//fuege Offsets fuer Parameter hinzu, hoth: 06.04.2006
Class.isFirstLocalVarDecl=false;
if(this.get_Block() != null)
this.get_Block().addOffsetsToAssumption(paraAssum,paraAssum.getIdentifier(),true);
methodAssum.addParaAssumption(paraAssum);
// F<>r die V_i:
CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(classmember.getName(), this.get_Method_Name(), this.getParameterCount(), this.getOverloadedID(),"1", para.get_Name(),para.getType(), para.getLineNumber(),para.getOffset(),new Vector<Integer>());
localAssum.addElement(varAssum);
//rememberLocals.addElement(varAssum);
}
}
//...und hinzuf<75>gen:
assumptions.add(localAssum);//Assumptions f<>r lokale Variablen den Assumptions hinzuf<75>gen
//Hier wird der Typ der als Assumption eingetragen wird in die Variable assumedType dieser Klasse geschrieben:
if(this.assumedType == null) // Falls der Typ nicht schon gesetzt ist. Das ist der Fall, falls die Methode ein Konstruktor ist
this.assumedType = methodAssum.getAssumedType();
return assumptions;
*/
2013-10-18 11:33:46 +00:00
}
2014-02-12 01:12:12 +00:00
@Override
public void parserPostProcessing(SyntaxTreeNode parent){
super.parserPostProcessing(parent);
if(this.getType()==null)this.setType(TypePlaceholder.fresh(this));
//Bei dem Elterntyp der Methode darf es sich nur um eine Klasse handeln, daher Cast ohne Pr<50>fung:
Class parentClass = (Class)parent;
2014-02-19 04:20:54 +00:00
if(this.returntype == null)this.returntype = TypePlaceholder.fresh(this);
2014-02-12 01:12:12 +00:00
}
@Override
public Vector<SyntaxTreeNode> getChildren() {
Vector<SyntaxTreeNode> ret = new Vector<SyntaxTreeNode>();
2014-02-12 01:12:12 +00:00
ret.add(this.block);
for(FormalParameter param : this.parameterlist){
ret.add(param);
}
2014-02-12 01:12:12 +00:00
return ret;
}
@Override
public void setType(Type t){
// Methode und Block teilen sich einen ReturnType:
2014-02-19 04:20:54 +00:00
//this.block.setType(t);
this.returntype = t;
2014-02-12 01:12:12 +00:00
}
2014-02-19 16:32:43 +00:00
/**
* Der Typ einer Methode ist ihr Returntype
*/
2014-02-12 01:12:12 +00:00
@Override
public Type getType(){
//Methode und Block teilen sich einen ReturnType:
2014-02-19 05:09:59 +00:00
return this.returntype;
2014-02-12 01:12:12 +00:00
}
2014-02-19 04:20:54 +00:00
public static Method createEmptyMethod(String withSignature, Class parent){
Method ret = new Method(0);
2014-02-19 04:20:54 +00:00
DeclId DImethod = new DeclId();
DImethod.set_Name(withSignature);
ret.set_DeclId(DImethod);
Block tempBlock = new Block();
//tempBlock.setType(new RefType(parent.getName(),0));
ret.set_Block(tempBlock);
2014-02-19 16:32:43 +00:00
ret.parserPostProcessing(parent);
2014-02-19 04:20:54 +00:00
return ret;
}
2013-10-18 11:33:46 +00:00
}
// ino.end