public void parse(MethodVisitor mw, int local,
Map<String, Integer> variableNames) {
Integer oldItemValue = null;
Integer oldKeyValue = null;
IExpression item = getParameter(1);
IExpression key = getParameter(2);
Label isnull = new Label();
Label isnotmap = new Label();
Label loopinit = new Label();
Label setstart = new Label();
Label setend = new Label();
Label setlist = new Label();
Label loopend = new Label();
Label end = new Label();
getParameter(0).parseObject(mw, local, variableNames);
mw.visitVarInsn(ASTORE, local);
mw.visitVarInsn(ALOAD, local);
mw.visitJumpInsn(IFNULL, isnull);
if (variableNames != null) {
oldItemValue = variableNames.get(item.toString());
variableNames.put(item.toString(), Integer.valueOf(local + 1));
if (key != null) {
oldKeyValue = variableNames.get(key.toString());
variableNames.put(key.toString(), Integer.valueOf(local + 2));
}
} else {
// 保存原始的循环变量名值
mw.visitVarInsn(ALOAD, CONTEXT);
item.parse(mw, local + 1, variableNames);
mw.visitInsn(DUP2);
mw.visitMethodInsn(INVOKEVIRTUAL, Context.NAME, "get",
"(Ljava/lang/String;)Ljava/lang/Object;");
if (key != null) {
mw.visitVarInsn(ALOAD, CONTEXT);
key.parse(mw, local + 2, variableNames);
mw.visitInsn(DUP2);
mw.visitMethodInsn(INVOKEVIRTUAL, Context.NAME, "get",
"(Ljava/lang/String;)Ljava/lang/Object;");
}
}
mw.visitVarInsn(ALOAD, local);
mw.visitMethodInsn(INVOKESTATIC, NAME, "getLooper",
"(Ljava/lang/Object;)[Ljava/lang/Object;");
mw.visitVarInsn(ALOAD, local);
mw.visitTypeInsn(INSTANCEOF, "java/util/Map");
mw.visitJumpInsn(IFEQ, isnotmap);
mw.visitVarInsn(ALOAD, local);
mw.visitTypeInsn(CHECKCAST, "java/util/Map");
mw.visitJumpInsn(GOTO, loopinit);
mw.visitLabel(isnotmap);
mw.visitInsn(ACONST_NULL);
mw.visitLabel(loopinit);
mw.visitVarInsn(ASTORE, local);
mw.visitInsn(DUP);
mw.visitInsn(ARRAYLENGTH);
mw.visitInsn(ICONST_0);
mw.visitVarInsn(ISTORE, local + 3);
mw.visitLabel(setstart);
mw.visitInsn(DUP2);
mw.visitVarInsn(ILOAD, local + 3);
mw.visitJumpInsn(IF_ICMPEQ, loopend);
if (getParameter(3) != null) {
mw.visitVarInsn(ASTORE, local + 4);
mw.visitInsn(DUP);
mw.visitVarInsn(ALOAD, CONTEXT);
mw.visitInsn(SWAP);
getParameter(3).parse(mw, local + 5, variableNames);
mw.visitVarInsn(ILOAD, local + 3);
mw.visitMethodInsn(INVOKEVIRTUAL, Context.NAME, "setForeach",
"(ILjava/lang/String;I)V");
mw.visitVarInsn(ALOAD, local + 4);
}
if (variableNames == null) {
mw.visitVarInsn(ALOAD, CONTEXT);
mw.visitInsn(SWAP);
item.parse(mw, local + 4, variableNames);
mw.visitInsn(SWAP);
}
mw.visitVarInsn(ILOAD, local + 3);
mw.visitInsn(AALOAD);
mw.visitVarInsn(ALOAD, local);
mw.visitJumpInsn(IFNULL, setlist);
// 循环源集合是Map型时所执行的处理
if (key != null) {
mw.visitInsn(DUP);
mw.visitMethodInsn(INVOKEINTERFACE, "java/util/Map$Entry", "getKey",
"()Ljava/lang/Object;");
// 是否设置主键的值
if (variableNames != null) {
mw.visitVarInsn(ASTORE, local + 2);
} else {
mw.visitVarInsn(ALOAD, CONTEXT);
mw.visitInsn(SWAP);
key.parse(mw, local + 4, variableNames);
mw.visitInsn(SWAP);
mw.visitMethodInsn(INVOKEVIRTUAL, Context.NAME, "set",
"(Ljava/lang/String;Ljava/lang/Object;)V");
}
}
mw.visitMethodInsn(INVOKEINTERFACE, "java/util/Map$Entry", "getValue",
"()Ljava/lang/Object;");
mw.visitJumpInsn(GOTO, setend);
// 循环源集合是List型时所执行的处理
mw.visitLabel(setlist);
if (key != null) {
if (variableNames == null) {
// 是否设置主键的值, 按数字编号
mw.visitVarInsn(ALOAD, CONTEXT);
key.parse(mw, local + 4, variableNames);
}
mw.visitVarInsn(ILOAD, local + 3);
mw.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf",
"(I)Ljava/lang/Integer;");
if (variableNames != null) {
mw.visitVarInsn(ASTORE, local + 2);
} else {
mw.visitMethodInsn(INVOKEVIRTUAL, Context.NAME, "set",
"(Ljava/lang/String;Ljava/lang/Object;)V");
}
}
mw.visitLabel(setend);
if (variableNames != null) {
mw.visitVarInsn(ASTORE, local + 1);
} else {
mw.visitMethodInsn(INVOKEVIRTUAL, Context.NAME, "set",
"(Ljava/lang/String;Ljava/lang/Object;)V");
}
super.parse(mw, local + 4, variableNames);
mw.visitLabel(startLabel);
mw.visitIincInsn(local + 3, 1);
mw.visitJumpInsn(GOTO, setstart);
mw.visitLabel(loopend);
mw.visitInsn(POP);
// 循环结束, 恢复恢复过程中被设置的属性的原始值
mw.visitLabel(endLabel);
restore(mw, variableNames);
mw.visitJumpInsn(GOTO, end);
// 循环源集合为空时的处理
mw.visitLabel(isnull);
if (elseBlock != null) {
elseBlock.parse(mw, local, variableNames);
}
mw.visitLabel(end);
if (variableNames != null) {
variableNames.put(item.toString(), oldItemValue);
if (key != null) {
variableNames.put(key.toString(), oldKeyValue);
}
}
}