private boolean blockEndsInBreakReturnThrow(Tree.Block that) {
   int size = that.getStatements().size();
   if (size > 0) {
     Tree.Statement s = that.getStatements().get(size - 1);
     return s instanceof Tree.Break || s instanceof Tree.Return || s instanceof Tree.Throw;
   } else {
     return false;
   }
 }
Example #2
0
  static void attributeArgument(final Tree.AttributeArgument that, final GenerateJsVisitor gen) {
    gen.out("(function()");
    gen.beginBlock();
    if (gen.opts.isVerbose() && that.getParameter() != null) {
      gen.out("//AttributeArgument ", that.getParameter().getName());
      gen.location(that);
      gen.endLine();
    }

    Tree.Block block = that.getBlock();
    Tree.SpecifierExpression specExpr = that.getSpecifierExpression();
    if (specExpr != null) {
      gen.out("return ");
      if (!gen.isNaturalLiteral(specExpr.getExpression().getTerm())) {
        gen.visitSingleExpression(specExpr.getExpression());
      }
    } else if (block != null) {
      gen.visitStatements(block.getStatements());
    }

    gen.endBlock();
    gen.out("())");
  }
  @Override
  public void visit(Tree.WhileStatement that) {
    Tree.WhileClause whileClause = that.getWhileClause();
    Tree.ConditionList conditionList = whileClause.getConditionList();
    Tree.ConditionList cl = conditionList;
    if (cl != null) {
      cl.visit(this);
    }

    boolean d = beginDeclarationScope();
    SpecificationState as = beginSpecificationScope();
    Tree.Block block = whileClause.getBlock();
    if (block != null) {
      if (isVariable() || isLate()) {
        block.visit(this);
      } else {
        boolean c = inLoop;
        inLoop = true;
        block.visit(this);
        inLoop = c;
      }
    }
    boolean possiblyAssignedByWhileClause = specified.possibly;
    boolean definitelyAssignedByWhileClause = specified.definitely;

    endDeclarationScope(d);
    endSpecificationScope(as);

    specified.definitely =
        specified.definitely
            || (definitelyAssignedByWhileClause && isAlwaysSatisfied(conditionList));
    specified.possibly =
        specified.possibly || (possiblyAssignedByWhileClause && !isNeverSatisfied(conditionList));

    checkDeclarationSection(that);
  }
  @Override
  public void visit(Tree.Block that) {
    Scope scope = that.getScope();
    if (scope instanceof Constructor) {
      if (definitelyInitedBy.contains(delegatedConstructor)) {
        specified.definitely = true;
      }
      if (possiblyInitedBy.contains(delegatedConstructor)) {
        specified.possibly = true;
      }
      delegatedConstructor = null;
    }

    boolean oe = endsInBreakReturnThrow;
    Tree.Continue olc = lastContinue;
    Tree.Statement olcs = lastContinueStatement;
    // rather nasty way of detecting that the continue
    // occurs in another conditional branch of the
    // statement containing this block, even though we
    // did not find it in _this_ branch
    boolean continueInSomeBranchOfCurrentConditional =
        lastContinue != null && lastContinueStatement == null;
    boolean blockEndsInBreakReturnThrow = blockEndsInBreakReturnThrow(that);
    endsInBreakReturnThrow = endsInBreakReturnThrow || blockEndsInBreakReturnThrow;
    Tree.Continue last = null;
    Tree.Statement lastStatement = null;
    for (Tree.Statement st : that.getStatements()) {
      ContinueVisitor cv = new ContinueVisitor(olc);
      st.visit(cv);
      if (cv.node != null) {
        last = cv.node;
        lastStatement = st;
      }
      if (cv.found) {
        olc = null;
        olcs = null;
      }
    }
    if (blockEndsInBreakReturnThrow || continueInSomeBranchOfCurrentConditional) {
      lastContinue = last;
      lastContinueStatement = lastStatement;
    }
    super.visit(that);
    endsInBreakReturnThrow = oe;
    lastContinue = olc;
    lastContinueStatement = olcs;

    if (scope instanceof Constructor) {
      Constructor c = (Constructor) scope;
      if (specified.definitely) {
        definitelyInitedBy.add(c);
      }
      if (specified.possibly) {
        possiblyInitedBy.add(c);
      }
    }
    if (isNonPartialConstructor(scope) && declaration.getContainer() == scope.getContainer()) {
      if (!specified.definitely) {
        initedByEveryConstructor = false;
      }
    }
  }
  @Override
  public void visit(Tree.IfStatement that) {
    if (that == lastContinueStatement) {
      lastContinueStatement = null;
    }

    Tree.IfClause ifClause = that.getIfClause();
    Tree.ConditionList conditionList = ifClause.getConditionList();
    if (ifClause != null) {
      Tree.ConditionList cl = conditionList;
      if (cl != null) {
        cl.visit(this);
      }
    }

    boolean d = beginDeclarationScope();
    SpecificationState as = beginSpecificationScope();
    if (ifClause != null) {
      Tree.Block block = ifClause.getBlock();
      if (block != null) {
        block.visit(this);
      }
    }
    boolean definitelyAssignedByIfClause = specified.definitely || specified.exited;
    boolean possiblyAssignedByIfClause = specified.possibly;
    boolean possiblyExitedFromIfClause = specified.exited;
    boolean specifiedByExitsFromIfClause = specified.byExits;
    endDeclarationScope(d);
    endSpecificationScope(as);

    boolean definitelyAssignedByElseClause;
    boolean possiblyAssignedByElseClause;
    boolean possiblyExitedFromElseClause;
    boolean specifiedByExitsFromElseClause;
    Tree.ElseClause elseClause = that.getElseClause();
    if (elseClause != null) {
      d = beginDeclarationScope();
      as = beginSpecificationScope();
      elseClause.visit(this);
      definitelyAssignedByElseClause = specified.definitely || specified.exited;
      possiblyAssignedByElseClause = specified.possibly;
      possiblyExitedFromElseClause = specified.exited;
      specifiedByExitsFromElseClause = specified.byExits;
      endDeclarationScope(d);
      endSpecificationScope(as);
    } else {
      definitelyAssignedByElseClause = false;
      possiblyAssignedByElseClause = false;
      possiblyExitedFromElseClause = false;
      specifiedByExitsFromElseClause = true;
    }

    if (isAlwaysSatisfied(conditionList)) {
      specified.definitely = specified.definitely || definitelyAssignedByIfClause;
      specified.possibly = specified.possibly || possiblyAssignedByIfClause;
      specified.exited = specified.exited || possiblyExitedFromIfClause;
      specified.byExits = specified.byExits && specifiedByExitsFromIfClause;
    } else if (isNeverSatisfied(conditionList)) {
      specified.definitely = specified.definitely || definitelyAssignedByElseClause;
      specified.possibly = specified.possibly || possiblyAssignedByElseClause;
      specified.exited = specified.exited || possiblyExitedFromElseClause;
      specified.byExits = specified.byExits && specifiedByExitsFromElseClause;
    } else {
      specified.definitely =
          specified.definitely || definitelyAssignedByIfClause && definitelyAssignedByElseClause;
      specified.possibly =
          specified.possibly || possiblyAssignedByIfClause || possiblyAssignedByElseClause;
      specified.exited =
          specified.exited || possiblyExitedFromIfClause || possiblyExitedFromElseClause;
      specified.byExits =
          specified.byExits && specifiedByExitsFromIfClause && specifiedByExitsFromElseClause;
    }

    checkDeclarationSection(that);
  }