📄 gen.java
字号:
{ super.visitApply(tree); complexity+=2; } public void visitNewClass(JCNewClass tree) { scan(tree.encl); scan(tree.args); complexity+=2; } public void visitNewArray(JCNewArray tree) { super.visitNewArray(tree); complexity+=5; } public void visitAssign(JCAssign tree) { super.visitAssign(tree); complexity+=1; } public void visitAssignop(JCAssignOp tree) { super.visitAssignop(tree); complexity+=2; } public void visitUnary(JCUnary tree) { complexity+=1; if (tree.type.constValue() == null) super.visitUnary(tree); } public void visitBinary(JCBinary tree) { complexity+=1; if (tree.type.constValue() == null) super.visitBinary(tree); } public void visitTypeTest(JCInstanceOf tree) { super.visitTypeTest(tree); complexity+=1; } public void visitIndexed(JCArrayAccess tree) { super.visitIndexed(tree); complexity+=1; } public void visitSelect(JCFieldAccess tree) { super.visitSelect(tree); if (tree.sym.kind == VAR) complexity+=1; } public void visitIdent(JCIdent tree) { if (tree.sym.kind == VAR) { complexity+=1; if (tree.type.constValue() == null && tree.sym.owner.kind == TYP) complexity+=1; } } public void visitLiteral(JCLiteral tree) { complexity+=1; } public void visitTree(JCTree tree) {} public void visitWildcard(JCWildcard tree) { throw new AssertionError(this.getClass().getName()); } } ComplexityScanner scanner = new ComplexityScanner(); tree.accept(scanner); return scanner.complexity; } public void visitIf(JCIf tree) { int limit = code.nextreg; Chain thenExit = null; CondItem c = genCond(TreeInfo.skipParens(tree.cond), CRT_FLOW_CONTROLLER); Chain elseChain = c.jumpFalse(); if (!c.isFalse()) { code.resolve(c.trueJumps); genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); thenExit = code.branch(goto_); } if (elseChain != null) { code.resolve(elseChain); if (tree.elsepart != null) genStat(tree.elsepart, env,CRT_STATEMENT | CRT_FLOW_TARGET); } code.resolve(thenExit); code.endScopes(limit); } public void visitExec(JCExpressionStatement tree) { // Optimize x++ to ++x and x-- to --x. JCExpression e = tree.expr; switch (e.getTag()) { case JCTree.POSTINC: ((JCUnary) e).setTag(JCTree.PREINC); break; case JCTree.POSTDEC: ((JCUnary) e).setTag(JCTree.PREDEC); break; } genExpr(tree.expr, tree.expr.type).drop(); } public void visitBreak(JCBreak tree) { Env<GenContext> targetEnv = unwind(tree.target, env); assert code.state.stacksize == 0; targetEnv.info.addExit(code.branch(goto_)); endFinalizerGaps(env, targetEnv); } public void visitContinue(JCContinue tree) { Env<GenContext> targetEnv = unwind(tree.target, env); assert code.state.stacksize == 0; targetEnv.info.addCont(code.branch(goto_)); endFinalizerGaps(env, targetEnv); } public void visitReturn(JCReturn tree) { int limit = code.nextreg; final Env<GenContext> targetEnv; if (tree.expr != null) { Item r = genExpr(tree.expr, pt).load(); if (hasFinally(env.enclMethod, env)) { r = makeTemp(pt); r.store(); } targetEnv = unwind(env.enclMethod, env); r.load(); code.emitop0(ireturn + Code.truncate(Code.typecode(pt))); } else { targetEnv = unwind(env.enclMethod, env); code.emitop0(return_); } endFinalizerGaps(env, targetEnv); code.endScopes(limit); } public void visitThrow(JCThrow tree) { genExpr(tree.expr, tree.expr.type).load(); code.emitop0(athrow); }/* ************************************************************************ * Visitor methods for expressions *************************************************************************/ public void visitApply(JCMethodInvocation tree) { // Generate code for method. Item m = genExpr(tree.meth, methodType); // Generate code for all arguments, where the expected types are // the parameters of the method's external type (that is, any implicit // outer instance of a super(...) call appears as first parameter). genArgs(tree.args, TreeInfo.symbol(tree.meth).externalType(types).getParameterTypes()); result = m.invoke(); } public void visitConditional(JCConditional tree) { Chain thenExit = null; CondItem c = genCond(tree.cond, CRT_FLOW_CONTROLLER); Chain elseChain = c.jumpFalse(); if (!c.isFalse()) { code.resolve(c.trueJumps); int startpc = genCrt ? code.curPc() : 0; genExpr(tree.truepart, pt).load(); code.state.forceStackTop(tree.type); if (genCrt) code.crt.put(tree.truepart, CRT_FLOW_TARGET, startpc, code.curPc()); thenExit = code.branch(goto_); } if (elseChain != null) { code.resolve(elseChain); int startpc = genCrt ? code.curPc() : 0; genExpr(tree.falsepart, pt).load(); code.state.forceStackTop(tree.type); if (genCrt) code.crt.put(tree.falsepart, CRT_FLOW_TARGET, startpc, code.curPc()); } code.resolve(thenExit); result = items.makeStackItem(pt); } public void visitNewClass(JCNewClass tree) { // Enclosing instances or anonymous classes should have been eliminated // by now. assert tree.encl == null && tree.def == null; code.emitop2(new_, makeRef(tree.pos(), tree.type)); code.emitop0(dup); // Generate code for all arguments, where the expected types are // the parameters of the constructor's external type (that is, // any implicit outer instance appears as first parameter). genArgs(tree.args, tree.constructor.externalType(types).getParameterTypes()); items.makeMemberItem(tree.constructor, true).invoke(); result = items.makeStackItem(tree.type); } public void visitNewArray(JCNewArray tree) { if (tree.elems != null) { Type elemtype = types.elemtype(tree.type); loadIntConst(tree.elems.length()); Item arr = makeNewArray(tree.pos(), tree.type, 1); int i = 0; for (List<JCExpression> l = tree.elems; l.nonEmpty(); l = l.tail) { arr.duplicate(); loadIntConst(i); i++; genExpr(l.head, elemtype).load(); items.makeIndexedItem(elemtype).store(); } result = arr; } else { for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) { genExpr(l.head, syms.intType).load(); } result = makeNewArray(tree.pos(), tree.type, tree.dims.length()); } }//where /** Generate code to create an array with given element type and number * of dimensions. */ Item makeNewArray(DiagnosticPosition pos, Type type, int ndims) { Type elemtype = types.elemtype(type); if (types.dimensions(elemtype) + ndims > ClassFile.MAX_DIMENSIONS) { log.error(pos, "limit.dimensions"); nerrs++; } int elemcode = Code.arraycode(elemtype); if (elemcode == 0 || (elemcode == 1 && ndims == 1)) { code.emitAnewarray(makeRef(pos, elemtype), type); } else if (elemcode == 1) { code.emitMultianewarray(ndims, makeRef(pos, type), type); } else { code.emitNewarray(elemcode, type); } return items.makeStackItem(type); } public void visitParens(JCParens tree) { result = genExpr(tree.expr, tree.expr.type); } public void visitAssign(JCAssign tree) { Item l = genExpr(tree.lhs, tree.lhs.type); genExpr(tree.rhs, tree.lhs.type).load(); result = items.makeAssignItem(l); } public void visitAssignop(JCAssignOp tree) { OperatorSymbol operator = (OperatorSymbol) tree.operator; Item l; if (operator.opcode == string_add) { // Generate code to make a string buffer makeStringBuffer(tree.pos()); // Generate code for first string, possibly save one // copy under buffer l = genExpr(tree.lhs, tree.lhs.type); if (l.width() > 0) { code.emitop0(dup_x1 + 3 * (l.width() - 1)); } // Load first string and append to buffer. l.load(); appendString(tree.lhs); // Append all other strings to buffer. appendStrings(tree.rhs); // Convert buffer to string. bufferToString(tree.pos()); } else { // Generate code for first expression l = genExpr(tree.lhs, tree.lhs.type); // If we have an increment of -32768 to +32767 of a local // int variable we can use an incr instruction instead of // proceeding further. if ((tree.getTag() == JCTree.PLUS_ASG || tree.getTag() == JCTree.MINUS_ASG) && l instanceof LocalItem && tree.lhs.type.tag <= INT && tree.rhs.type.tag <= INT && tree.rhs.type.constValue() != null) { int ival = ((Number) tree.rhs.type.constValue()).intValue(); if (tree.getTag() == JCTree.MINUS_ASG) ival = -ival; ((LocalItem)l).incr(ival); result = l; return; } // Otherwise, duplicate expression, load one copy // and complete binary operation. l.duplicate(); l.coerce(operator.type.getParameterTypes().head).load(); completeBinop(tree.lhs, tree.rhs, operator).coerce(tree.lhs.type); } result = items.makeAssignItem(l); } public void visitUnary(JCUnary tree) { OperatorSymbol operator = (OperatorSymbol)tree.operator; if (tree.getTag() == JCTree.NOT) { CondItem od = genCond(tree.arg, false); result = od.negate(); } else { Item od = genExpr(tree.arg, operator.type.getParameterTypes().head); switch (tree.getTag()) { case JCTree.POS: result = od.load(); break; case JCTree.NEG: result = od.load(); code.emitop0(operator.opcode); break; case JCTree.COMPL: result = od.load(); emitMinusOne(od.typecode); code.emitop0(operator.opcode); break; case JCTree.PREINC: case JCTree.PREDEC: od.duplicate(); if (od instanceof LocalItem && (operator.opcode == iadd || operator.opcode == isub)) { ((LocalItem)od).incr(tree.getTag() == JCTree.PREINC ? 1 : -1); result = od; } else { od.load(); code.emitop0(one(od.typecode)); code.emitop0(operator.opcode); // Perform narrowing primitive conversion if byte, // char, or short. Fix for 4304655. if (od.typecode != INTcode && Code.truncate(od.typecode) == INTcode) code.emitop0(int2byte + od.typecode - BYTEcode); result = items.makeAssignItem(od); } break; case JCTree.POSTINC: case JCTree.POSTDEC: od.duplicate(); if (od instanceof LocalItem && (operator.opcode == iadd || operator.opcode == isub)) { Item res = od.load(); ((LocalItem)od).incr(tree.getTag() == JCTree.POSTINC ? 1 : -1); result = res; } else { Item res = od.load(); od.stash(od.typecode); code.emitop0(one(od.typecode)); code.emitop0(operator.opcode); // Perform narrowing primitive conversion if byte, // char, or short. Fix for 4304655. if (od.typecode != INTcode && Code.truncate(od.typecode) == INTcode) code.emitop0(int2byte + od.typecode - BYTEcode); od.store(); result = res; } break; case JCTree.NULLCHK: result = od.load(); code.emitop0(dup); genNullCheck(tree.pos()); break; default: assert false; } } } /** Generate a null check from the object value at stack top. */ private void genNullCheck(DiagnosticPosition pos) { callMethod(pos, syms.objectType, names.getClass, List.<Type>nil(), false); code.emitop0(pop); } public void visitBinary(JCBinary tree) { OperatorSymbol operator = (OperatorSymbol)tree.operator; if (operator.opcode == string_add) { // Create a string buffer. makeStringBuffer(tree.pos()); // Append all strings to buffer. appendStrings(tree); // Convert buffer to string. bufferToString(tree.pos()); result = items.makeStackItem(syms.stringType); } else if (tree.getTag() == JCTree.AND) { CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER); if (!lcond.isFalse()) { Chain falseJumps = lcond.jumpFalse(); code.resolve(lcond.trueJumps); CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET); result = items. makeCondItem(rcond.opcode, rcond.trueJumps, code.mergeChains(falseJumps, rcond.falseJumps)); } else { result = lcond; } } else if (tree.getTag() == JCTree.OR) { CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER); if (!lcond.isTrue()) { Chain trueJumps = lcond.jumpTrue(); code.resolve(lcond.falseJumps); CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET); result = items. makeCondItem(rcond.opcode, code.mergeChains(trueJumps, rcond.trueJumps), rcond.falseJumps); } else { result = lcond;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -