public void visitSwitch(SwitchStatement statement) { statement.getExpression().visit(this); for (CaseStatement caseStatement : statement.getCaseStatements()) { caseStatement.visit(this); } statement.getDefaultStatement().visit(this); }
public final java_cup.runtime.Symbol do_action( int CUP$parser$act_num, java_cup.runtime.lr_parser CUP$parser$parser, java.util.Stack CUP$parser$stack, int CUP$parser$top, parser parser) throws java.lang.Exception { java_cup.runtime.Symbol CUP$parser$result; // c_selection_statement ::= K_SWITCH error c_statement { Statement RESULT = null; Token rl = (Token) ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top - 2)).value; Statement s = (Statement) ((java_cup.runtime.Symbol) CUP$parser$stack.peek()).value; SwitchStatement result = new SwitchStatement( parser.errorNode( "switch header", "expression", rl.getRight(), s.getRange().getLeft()), s); RESULT = result; result.setLeft(rl.getLeft()); CUP$parser$result = parser .getSymbolFactory() .newSymbol( "c_selection_statement", 128, ((java_cup.runtime.Symbol) CUP$parser$stack.elementAt(CUP$parser$top - 2)), ((java_cup.runtime.Symbol) CUP$parser$stack.peek()), RESULT); } return CUP$parser$result; }
@Override public Void visitSwitchStatement(SwitchStatement node) { writer.print("switch ("); visit(node.getExpression()); writer.print(") {"); visitList(node.getMembers(), " "); writer.print("}"); return null; }
/* * @see ASTVisitor#visit(SwitchStatement) */ @Override public boolean visit(SwitchStatement node) { this.fBuffer.append("switch ("); // $NON-NLS-1$ node.getExpression().accept(this); this.fBuffer.append(") "); // $NON-NLS-1$ this.fBuffer.append("{"); // $NON-NLS-1$ for (Iterator<Statement> it = node.statements().iterator(); it.hasNext(); ) { Statement s = it.next(); s.accept(this); } this.fBuffer.append("}"); // $NON-NLS-1$ return false; }
@Override public void visit(SwitchStatement statement) { statement.getValue().acceptVisitor(this); statement.setValue(resultExpr); for (SwitchClause clause : statement.getClauses()) { List<Statement> newBody = processSequence(clause.getBody()); clause.getBody().clear(); clause.getBody().addAll(newBody); } List<Statement> newDefault = processSequence(statement.getDefaultClause()); statement.getDefaultClause().clear(); statement.getDefaultClause().addAll(newDefault); resultStmt = statement; }
@Override public void visit(SwitchInstruction insn) { SwitchStatement stmt = new SwitchStatement(); stmt.setId("sblock" + (lastSwitchId++)); stmt.setValue(Expr.var(insn.getCondition().getIndex())); Map<Integer, List<Integer>> switchMap = new HashMap<>(); for (int i = 0; i < insn.getEntries().size(); ++i) { SwitchTableEntry entry = insn.getEntries().get(i); List<Integer> conditions = switchMap.get(entry.getTarget().getIndex()); if (conditions == null) { conditions = new ArrayList<>(); switchMap.put(entry.getTarget().getIndex(), conditions); } conditions.add(entry.getCondition()); } List<Integer> targets = new ArrayList<>(switchMap.keySet()); Collections.sort(targets); for (int target : targets) { SwitchClause clause = new SwitchClause(); List<Integer> conditionList = switchMap.get(target); int[] conditions = new int[conditionList.size()]; for (int i = 0; i < conditionList.size(); ++i) { conditions[i] = conditionList.get(i); } clause.setConditions(conditions); Statement jumpStmt = generateJumpStatement(stmt, target); if (jumpStmt != null) { clause.getBody().add(jumpStmt); } stmt.getClauses().add(clause); } Statement breakStmt = generateJumpStatement(insn.getDefaultTarget()); if (breakStmt != null) { stmt.getDefaultClause().add(breakStmt); } statements.add(stmt); }
public void testLinenoSwitch() { AstRoot root = parse( "\nswitch (a) {\n" + " case\n" + " 1:\n" + " b++;\n" + " case 2:\n" + " default:\n" + " b--;\n" + " }\n"); SwitchStatement switchStmt = (SwitchStatement) root.getFirstChild(); AstNode switchVar = switchStmt.getExpression(); List<SwitchCase> cases = switchStmt.getCases(); SwitchCase firstCase = cases.get(0); AstNode caseArg = firstCase.getExpression(); List<AstNode> caseBody = firstCase.getStatements(); ExpressionStatement exprStmt = (ExpressionStatement) caseBody.get(0); UnaryExpression incrExpr = (UnaryExpression) exprStmt.getExpression(); AstNode incrVar = incrExpr.getOperand(); SwitchCase secondCase = cases.get(1); AstNode defaultCase = cases.get(2); AstNode returnStmt = (AstNode) switchStmt.getNext(); assertEquals(1, switchStmt.getLineno()); assertEquals(1, switchVar.getLineno()); assertEquals(2, firstCase.getLineno()); assertEquals(3, caseArg.getLineno()); assertEquals(4, exprStmt.getLineno()); assertEquals(4, incrExpr.getLineno()); assertEquals(4, incrVar.getLineno()); assertEquals(5, secondCase.getLineno()); assertEquals(6, defaultCase.getLineno()); }
private void eliminateRedundantBreaks(List<Statement> statements, IdentifiedStatement exit) { if (statements.isEmpty()) { return; } Statement last = statements.get(statements.size() - 1); if (last instanceof BreakStatement && exit != null) { IdentifiedStatement target = ((BreakStatement) last).getTarget(); if (exit == target) { statements.remove(statements.size() - 1); } } if (statements.isEmpty()) { return; } for (int i = 0; i < statements.size(); ++i) { Statement stmt = statements.get(i); if (stmt instanceof ConditionalStatement) { ConditionalStatement cond = (ConditionalStatement) stmt; check_conditional: { last = cond.getConsequent().isEmpty() ? null : cond.getConsequent().get(cond.getConsequent().size() - 1); if (last instanceof BreakStatement) { BreakStatement breakStmt = (BreakStatement) last; if (exit != null && exit == breakStmt.getTarget()) { cond.getConsequent().remove(cond.getConsequent().size() - 1); List<Statement> remaining = statements.subList(i + 1, statements.size()); cond.getAlternative().addAll(remaining); remaining.clear(); break check_conditional; } } last = cond.getAlternative().isEmpty() ? null : cond.getAlternative().get(cond.getAlternative().size() - 1); if (last instanceof BreakStatement) { BreakStatement breakStmt = (BreakStatement) last; if (exit != null && exit == breakStmt.getTarget()) { cond.getAlternative().remove(cond.getAlternative().size() - 1); List<Statement> remaining = statements.subList(i + 1, statements.size()); cond.getConsequent().addAll(remaining); remaining.clear(); } } } if (i == statements.size() - 1) { eliminateRedundantBreaks(cond.getConsequent(), exit); eliminateRedundantBreaks(cond.getAlternative(), exit); } normalizeConditional(cond); if (cond.getConsequent().size() == 1 && cond.getConsequent().get(0) instanceof ConditionalStatement) { ConditionalStatement innerCond = (ConditionalStatement) cond.getConsequent().get(0); if (innerCond.getAlternative().isEmpty()) { if (cond.getAlternative().isEmpty()) { cond.getConsequent().clear(); cond.getConsequent().addAll(innerCond.getConsequent()); cond.setCondition( Expr.binary( BinaryOperation.AND, cond.getCondition(), innerCond.getCondition(), cond.getCondition().getLocation())); --i; } else if (cond.getAlternative().size() != 1 || !(cond.getAlternative().get(0) instanceof ConditionalStatement)) { cond.setCondition(ExprOptimizer.invert(cond.getCondition())); cond.getConsequent().clear(); cond.getConsequent().addAll(cond.getAlternative()); cond.getAlternative().clear(); cond.getAlternative().add(innerCond); --i; } } } } else if (stmt instanceof BlockStatement) { BlockStatement nestedBlock = (BlockStatement) stmt; eliminateRedundantBreaks(nestedBlock.getBody(), nestedBlock); } else if (stmt instanceof WhileStatement) { WhileStatement whileStmt = (WhileStatement) stmt; eliminateRedundantBreaks(whileStmt.getBody(), null); } else if (stmt instanceof SwitchStatement) { SwitchStatement switchStmt = (SwitchStatement) stmt; for (SwitchClause clause : switchStmt.getClauses()) { eliminateRedundantBreaks(clause.getBody(), null); } eliminateRedundantBreaks(switchStmt.getDefaultClause(), null); } } }
/** * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then * answers Float.MIN_VALUE * * @see * org.aspectj.org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope, * org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding, * org.aspectj.org.eclipse.jdt.internal.compiler.ast.SwitchStatement) */ public Constant resolveCase( BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { // switchExpressionType maybe null in error case scope.enclosingCase = this; // record entering in a switch case block if (this.constantExpression == null) { // remember the default case into the associated switch statement if (switchStatement.defaultCase != null) scope.problemReporter().duplicateDefaultCase(this); // on error the last default will be the selected one ... switchStatement.defaultCase = this; return Constant.NotAConstant; } // add into the collection of cases of the associated switch statement switchStatement.cases[switchStatement.caseCount++] = this; // tag constant name with enum type for privileged access to its members if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) { ((SingleNameReference) this.constantExpression) .setActualReceiverType((ReferenceBinding) switchExpressionType); } TypeBinding caseType = this.constantExpression.resolveType(scope); if (caseType == null || switchExpressionType == null) return Constant.NotAConstant; if (this.constantExpression.isConstantValueOfTypeAssignableToType( caseType, switchExpressionType) || caseType.isCompatibleWith(switchExpressionType)) { if (caseType.isEnum()) { if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { scope .problemReporter() .enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression); } if (this.constantExpression instanceof NameReference && (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { NameReference reference = (NameReference) this.constantExpression; FieldBinding field = reference.fieldBinding(); if ((field.modifiers & ClassFileConstants.AccEnum) == 0) { scope.problemReporter().enumSwitchCannotTargetField(reference, field); } else if (reference instanceof QualifiedNameReference) { scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field); } return IntConstant.fromValue( field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810 } } else { return this.constantExpression.constant; } } else if (isBoxingCompatible(caseType, switchExpressionType, this.constantExpression, scope)) { // constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not // report boxing/unboxing conversion return this.constantExpression.constant; } scope .problemReporter() .typeMismatchError( caseType, switchExpressionType, this.constantExpression, switchStatement.expression); return Constant.NotAConstant; }
public void collapseNodesToStatement(Statement stat) { Statement head = stat.getFirst(); Statement post = stat.getPost(); VBStyleCollection<Statement, Integer> setNodes = stat.getStats(); // post edges if (post != null) { for (StatEdge edge : post.getEdges(STATEDGE_DIRECT_ALL, DIRECTION_BACKWARD)) { if (stat.containsStatementStrict(edge.getSource())) { edge.getSource().changeEdgeType(DIRECTION_FORWARD, edge, StatEdge.TYPE_BREAK); stat.addLabeledEdge(edge); } } } // regular head edges for (StatEdge prededge : head.getAllPredecessorEdges()) { if (prededge.getType() != StatEdge.TYPE_EXCEPTION && stat.containsStatementStrict(prededge.getSource())) { prededge.getSource().changeEdgeType(DIRECTION_FORWARD, prededge, StatEdge.TYPE_CONTINUE); stat.addLabeledEdge(prededge); } head.removePredecessor(prededge); prededge.getSource().changeEdgeNode(DIRECTION_FORWARD, prededge, stat); stat.addPredecessor(prededge); } if (setNodes.containsKey(first.id)) { first = stat; } // exception edges Set<Statement> setHandlers = new HashSet<Statement>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); for (Statement node : setNodes) { setHandlers.retainAll(node.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); } if (!setHandlers.isEmpty()) { for (StatEdge edge : head.getEdges(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)) { Statement handler = edge.getDestination(); if (setHandlers.contains(handler)) { if (!setNodes.containsKey(handler.id)) { stat.addSuccessor(new StatEdge(stat, handler, edge.getExceptions())); } } } for (Statement node : setNodes) { for (StatEdge edge : node.getEdges(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)) { if (setHandlers.contains(edge.getDestination())) { node.removeSuccessor(edge); } } } } if (post != null && !stat.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD) .contains(post)) { // TODO: second condition redundant? stat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, stat, post)); } // adjust statement collection for (Statement st : setNodes) { stats.removeWithKey(st.id); } stats.addWithKey(stat, stat.id); stat.setAllParent(); stat.setParent(this); stat.buildContinueSet(); // monitorenter and monitorexit stat.buildMonitorFlags(); if (stat.type == TYPE_SWITCH) { // special case switch, sorting leaf nodes ((SwitchStatement) stat).sortEdgesAndNodes(); } }
@Override public Statement semantic(Scope sc, SemanticContext context) { SwitchStatement sw = sc.sw; this.sw = sw; exp = exp.semantic(sc, context); if (sw != null) { int i; exp = exp.implicitCastTo(sc, sw.condition.type, context); exp = exp.optimize(WANTvalue | WANTinterpret, context); boolean gotoL1 = false; if (context.isD2()) { /* This is where variables are allowed as case expressions. */ if (exp.op == TOKvar) { VarExp ve = (VarExp) exp; VarDeclaration v = ve.var.isVarDeclaration(); Type t = exp.type.toBasetype(context); if (v != null && (t.isintegral() || t.ty == Tclass)) { /* Flag that we need to do special code generation * for this, i.e. generate a sequence of if-then-else */ sw.hasVars = 1; // goto L1; gotoL1 = true; } } } if (!gotoL1) { if (exp.op != TOKstring && exp.op != TOKint64) { if (context.acceptsErrors()) { context.acceptProblem( Problem.newSemanticTypeError( IProblem.CaseMustBeAnIntegralOrStringConstant, sourceExp, exp.toChars(context))); } exp = new IntegerExp(0); } } // L1: for (i = 0; i < sw.cases.size(); i++) { CaseStatement cs = (CaseStatement) sw.cases.get(i); if (cs.exp.equals(exp, context)) { if (context.acceptsErrors()) { context.acceptProblem( Problem.newSemanticTypeErrorLoc( IProblem.DuplicateCaseInSwitchStatement, this, exp.toChars(context))); } break; } } sw.cases.add(this); // Resolve any goto case's with no exp to this case statement if (sw.gotoCases != null) { for (i = 0; i < sw.gotoCases.size(); i++) { GotoCaseStatement gcs = (GotoCaseStatement) sw.gotoCases.get(i); if (gcs.exp == null) { gcs.cs = this; sw.gotoCases.remove(i); // remove from array } } } if (context.isD2()) { if (sc.sw.tf != sc.tf) { if (context.acceptsErrors()) { context.acceptProblem( Problem.newSemanticTypeErrorLoc( IProblem.SwitchAndCaseAreInDifferentFinallyBlocks, this)); } } } } else { if (context.acceptsErrors()) { context.acceptProblem(Problem.newSemanticTypeError(IProblem.CaseIsNotInSwitch, this)); } } statement = statement.semantic(sc, context); return this; }