git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@118 379699f6-c40d-0410-875b-85095c16579estable
parent
0192af7705
commit
2f94432ce8
@ -0,0 +1,142 @@ |
||||
/* TransformConstructors Copyright (C) 1997-1998 Jochen Hoenicke. |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2, or (at your option) |
||||
* any later version. |
||||
* |
||||
* This program 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 for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; see the file COPYING. If not, write to |
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||
* |
||||
* $Id$ |
||||
*/ |
||||
package jode.flow; |
||||
import jode.ClassAnalyzer; |
||||
import jode.Expression; |
||||
import jode.ComplexExpression; |
||||
import jode.InvokeOperator; |
||||
import jode.PutFieldOperator; |
||||
|
||||
/** |
||||
* |
||||
* @author Jochen Hoenicke |
||||
*/ |
||||
public class TransformConstructors { |
||||
|
||||
public static void transform(ClassAnalyzer clazzAnalyzer, |
||||
boolean isStatic, |
||||
jode.MethodAnalyzer[] cons) { |
||||
if (cons.length == 0) |
||||
return; |
||||
|
||||
InstructionBlock[] superCall = new InstructionBlock[cons.length]; |
||||
StructuredBlock[] start = new StructuredBlock[cons.length]; |
||||
StructuredBlock[] sb = new StructuredBlock[cons.length]; |
||||
for (int i=0; i< sb.length; i++) { |
||||
sb[i] = cons[i].getMethodHeader().block; |
||||
if (sb[i] == null) |
||||
return; |
||||
if (!isStatic && |
||||
sb[i] instanceof SequentialBlock |
||||
&& sb[i].getSubBlocks()[0] instanceof InstructionBlock) { |
||||
superCall[i] = (InstructionBlock) sb[i].getSubBlocks()[0]; |
||||
|
||||
if (!(superCall[i].getInstruction().getOperator() |
||||
instanceof InvokeOperator) |
||||
|| !((InvokeOperator)superCall[i].getInstruction() |
||||
.getOperator()).isConstructor()) |
||||
superCall[i] = null; |
||||
else |
||||
/* skip super call */ |
||||
sb[i] = sb[i].getSubBlocks()[1]; |
||||
} |
||||
} |
||||
for (int i=0; i< sb.length; i++) |
||||
start[i] = sb[i]; |
||||
big_loop: |
||||
for (;;) { |
||||
StructuredBlock ib = |
||||
(sb[0] instanceof SequentialBlock) |
||||
? sb[0].getSubBlocks()[0] |
||||
: sb[0]; |
||||
if (!(ib instanceof InstructionBlock)) |
||||
break big_loop; |
||||
|
||||
Expression instr = ((InstructionBlock) ib).getInstruction(); |
||||
if (!(instr instanceof ComplexExpression) |
||||
|| !(instr.getOperator() instanceof PutFieldOperator) |
||||
|| (((PutFieldOperator)instr.getOperator()).isStatic() |
||||
!= isStatic)) |
||||
break big_loop; |
||||
|
||||
PutFieldOperator pfo = (PutFieldOperator) instr.getOperator(); |
||||
Expression expr = ((ComplexExpression)instr) |
||||
.getSubExpressions()[isStatic ? 0 : 1]; |
||||
|
||||
|
||||
if (!expr.isConstant()) { |
||||
// System.err.println("not constant: "+expr);
|
||||
break big_loop; |
||||
} |
||||
|
||||
// System.err.println("field "+pfo.getFieldName()+ " = "+expr);
|
||||
|
||||
if (!isStatic |
||||
&& !(((ComplexExpression)instr).getSubExpressions()[0] |
||||
.toString().equals("this"))) { |
||||
// System.err.println("not this: "+instr);
|
||||
break big_loop; |
||||
} |
||||
|
||||
for (int i=1; i< sb.length; i++) { |
||||
ib = (sb[0] instanceof SequentialBlock) |
||||
? sb[0].getSubBlocks()[0] |
||||
: sb[0]; |
||||
if (!(ib instanceof InstructionBlock) |
||||
|| !((InstructionBlock)ib).getInstruction().equals(instr)) { |
||||
// System.err.println("constr "+i+" differs: "+ib);
|
||||
break big_loop; |
||||
} |
||||
} |
||||
|
||||
|
||||
if (!clazzAnalyzer.setFieldInitializer(pfo.getFieldName(), expr)) { |
||||
// System.err.println("setField failed");
|
||||
break big_loop; |
||||
} |
||||
|
||||
|
||||
for (int i=0; i< sb.length; i++) { |
||||
if (sb[i] instanceof SequentialBlock) |
||||
sb[i] = sb[i].getSubBlocks()[1]; |
||||
else |
||||
sb[i] = null; |
||||
} |
||||
for (int i=0; i< sb.length; i++) |
||||
if (sb[i] == null) { |
||||
// System.err.println("constr "+i+" is over");
|
||||
break big_loop; |
||||
} |
||||
} |
||||
for (int i=0; i< superCall.length; i++) { |
||||
if (sb[i] == null) |
||||
start[i].removeBlock(); |
||||
else |
||||
sb[i].replace(start[i]); |
||||
if (superCall[i] != null) { |
||||
InvokeOperator op = |
||||
(InvokeOperator) superCall[i].getInstruction() |
||||
.getOperator(); |
||||
/* super() is implicit */ |
||||
if (op.getMethodType().getParameterTypes().length == 0) |
||||
superCall[i].removeBlock(); |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue