handle static inner classes (outerValues[0] missing in constructor$)

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@916 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 25 years ago
parent 76e9f0091f
commit a272c3b1df
  1. 87
      jode/jode/flow/TransformConstructors.java

@ -93,16 +93,18 @@ public class TransformConstructors implements OuterValueListener {
this.isStatic = isStatic; this.isStatic = isStatic;
this.cons = cons; this.cons = cons;
this.ovMinSlots = 1; this.ovMinSlots = 1;
ovMaxSlots = Integer.MAX_VALUE;
this.outerValues = clazzAnalyzer.getOuterValues(); this.outerValues = clazzAnalyzer.getOuterValues();
if (outerValues != null) { if (outerValues != null) {
clazzAnalyzer.addOuterValueListener(this); clazzAnalyzer.addOuterValueListener(this);
ovMaxSlots = Integer.MAX_VALUE;
updateOuterValues(outerValues.length); updateOuterValues(outerValues.length);
} } else
ovMaxSlots = 1;
} }
public void updateOuterValues(int count) { public void updateOuterValues(int count) {
int outerSlots = 1; int outerSlots = 1;
outerValues = clazzAnalyzer.getOuterValues();
if ((GlobalOptions.debuggingFlags if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_CONSTRS) != 0) & GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.print("OuterValues: "); GlobalOptions.err.print("OuterValues: ");
@ -114,7 +116,7 @@ public class TransformConstructors implements OuterValueListener {
} }
if (outerSlots < ovMaxSlots) if (outerSlots < ovMaxSlots)
ovMaxSlots = outerSlots; ovMaxSlots = outerSlots;
if (outerSlots < ovMinSlots) { if (ovMaxSlots < ovMinSlots) {
GlobalOptions.err.println GlobalOptions.err.println
("WARNING: something got wrong with scoped class " ("WARNING: something got wrong with scoped class "
+clazzAnalyzer.getClazz()+": "+ovMinSlots+","+ovMaxSlots); +clazzAnalyzer.getClazz()+": "+ovMinSlots+","+ovMaxSlots);
@ -253,9 +255,6 @@ public class TransformConstructors implements OuterValueListener {
} }
public boolean checkJikesContinuation(MethodAnalyzer constr) { public boolean checkJikesContinuation(MethodAnalyzer constr) {
if (outerValues == null)
return false;
MethodType constrType = constr.getType(); MethodType constrType = constr.getType();
/* /*
@ -272,10 +271,15 @@ public class TransformConstructors implements OuterValueListener {
* constructor$?(outerValues[0], params); * constructor$?(outerValues[0], params);
* } * }
* *
* The outerValues[0] parameter is the normal this of the
* surrounding method (but what is the surrounding method?
* That can't be determined in some cases). If the
* surrounding method is static, the outerValues[0] parameter
* disappears!
*
* Move optional super to method constructor$? * Move optional super to method constructor$?
* (renaming local variables) and mark constructor and * (renaming local variables) and mark constructor and
* constructor$? as Jikes constructor. * constructor$? as Jikes constructor. */
*/
StructuredBlock sb = constr.getMethodHeader().block; StructuredBlock sb = constr.getMethodHeader().block;
@ -345,11 +349,42 @@ public class TransformConstructors implements OuterValueListener {
if (methodAna == null) if (methodAna == null)
return false; return false;
MethodType methodType = methodAna.getType(); MethodType methodType = methodAna.getType();
Expression[] constrParams = invoke.getSubExpressions();
if (!methodAna.getName().startsWith("constructor$")
|| methodType.getReturnType() != Type.tVoid)
return false;
if (!isThis(invoke.getSubExpressions()[0],
clazzAnalyzer.getClazz()))
return false;
int ovLength = constrType.getParameterTypes().length int ovLength = constrType.getParameterTypes().length
- (methodType.getParameterTypes().length - 1); - methodType.getParameterTypes().length;
if (jikesAnonInner) if (jikesAnonInner)
ovLength--; ovLength--;
int firstArg = 1;
boolean unsureOuter = false;
boolean canHaveOuter = false;
if (outerValues != null && outerValues.length > 0
&& outerValues[0] instanceof ThisOperator
&& firstArg < constrParams.length
&& constrParams[firstArg] instanceof LocalLoadOperator
&& ((LocalLoadOperator)
constrParams[firstArg]).getLocalInfo().getSlot() == 1) {
if (ovLength == 0 && ovMinSlots == 1)
/* It is not sure, if outerValues[0] is present or not.
*/
unsureOuter = true;
/* Assume outerValues[0] is there */
ovLength++;
firstArg++;
canHaveOuter = true;
}
if (ovLength > outerValues.length) if (ovLength > outerValues.length)
return false; return false;
int ovSlots = 1; int ovSlots = 1;
@ -362,34 +397,12 @@ public class TransformConstructors implements OuterValueListener {
+ovSlots+" possible: [" +ovSlots+" possible: ["
+ovMinSlots+","+ovMaxSlots+"]"); +ovMinSlots+","+ovMaxSlots+"]");
if (!methodAna.getName().startsWith("constructor$") if (ovSlots < ovMinSlots || ovSlots > ovMaxSlots)
|| ovSlots < ovMinSlots || ovSlots > ovMaxSlots
|| methodType.getReturnType() != Type.tVoid)
return false; return false;
if (!isThis(invoke.getSubExpressions()[0],
clazzAnalyzer.getClazz()))
return false;
ClassInfo parent;
if (clazzAnalyzer.getParent() instanceof ClassAnalyzer)
parent = ((ClassAnalyzer) clazzAnalyzer.getParent())
.getClazz();
else if (clazzAnalyzer.getParent() instanceof MethodAnalyzer)
parent = ((MethodAnalyzer) clazzAnalyzer.getParent())
.getClazz();
else
return false;
Expression[] constrParams = invoke.getSubExpressions();
if (!isThis(outerValues[0], parent)
|| !(constrParams[1] instanceof LocalLoadOperator)
|| ((LocalLoadOperator)
constrParams[1]).getLocalInfo().getSlot() != 1)
return false;
{ {
int slot = ovSlots; int slot = ovSlots;
int start = 2; for (int j = firstArg; j < constrParams.length; j++) {
for (int j = start; j < constrParams.length; j++) {
if (!(constrParams[j] instanceof LocalLoadOperator)) if (!(constrParams[j] instanceof LocalLoadOperator))
return false; return false;
LocalLoadOperator llop LocalLoadOperator llop
@ -403,7 +416,11 @@ public class TransformConstructors implements OuterValueListener {
& GlobalOptions.DEBUG_CONSTRS) != 0) & GlobalOptions.DEBUG_CONSTRS) != 0)
GlobalOptions.err.println("jikesConstrCont succeded."); GlobalOptions.err.println("jikesConstrCont succeded.");
ovMinSlots = ovMaxSlots = ovSlots; if (unsureOuter) {
ovMaxSlots = 2;
} else {
ovMinSlots = ovMaxSlots = ovSlots;
}
if (superBlock != null if (superBlock != null
&& checkAnonymousConstructor(constr, superBlock)) { && checkAnonymousConstructor(constr, superBlock)) {
superBlock = null; superBlock = null;
@ -432,7 +449,7 @@ public class TransformConstructors implements OuterValueListener {
clazzAnalyzer.setJikesAnonymousInner(jikesAnonInner); clazzAnalyzer.setJikesAnonymousInner(jikesAnonInner);
constr.setJikesConstructor(true); constr.setJikesConstructor(true);
methodAna.setJikesConstructor(true); methodAna.setJikesConstructor(true);
methodAna.getParamInfo(1).setExpression(outerValues[0]); methodAna.setHasOuterValue(canHaveOuter);
methodAna.analyze(); methodAna.analyze();
if (constr.isAnonymousConstructor() if (constr.isAnonymousConstructor()
&& methodAna.getMethodHeader().block instanceof EmptyBlock) && methodAna.getMethodHeader().block instanceof EmptyBlock)

Loading…
Cancel
Save