public void visitSwitch(SwitchStatement statement) {
   statement.getExpression().visit(this);
   for (CaseStatement caseStatement : statement.getCaseStatements()) {
     caseStatement.visit(this);
   }
   statement.getDefaultStatement().visit(this);
 }
Beispiel #2
0
 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;
 }
Beispiel #3
0
 @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;
 }
Beispiel #5
0
 @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;
 }
Beispiel #6
0
 @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());
  }
Beispiel #8
0
 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;
  }