public boolean exec(TemplateNode template) {

    boolean hasOptional = false;
    for (TemplateParam param : template.getParams()) {
      if (param.isRequired()) {
        // If there exists a required param, then data should already be defined (no need to
        // ensure).
        return false;
      } else {
        hasOptional = true;
      }
    }
    if (hasOptional) {
      // If all params are optional (and there is at least one), then we need to ensure data is
      // defined.  This is because the only legal way to have an optional param is if you reference
      // it somewhere in the template, so there is no need to check.
      return true;
    }
    // If we get here then the template has no declared params and we are observing a v1 compatible
    // template.  Search for things that could be data references:
    // * possibleParams
    // * data=All calls
    // others?
    return new AbstractNodeVisitor<Node, Boolean>() {
      boolean shouldEnsureDataIsDefined;

      @Override
      public Boolean exec(Node node) {
        visit(node);
        return shouldEnsureDataIsDefined;
      }

      @Override
      public void visit(Node node) {
        if (node instanceof VarRefNode) {
          VarRefNode varRefNode = (VarRefNode) node;
          VarDefn var = varRefNode.getDefnDecl();
          // Don't include injected params in this analysis
          if (varRefNode.isPossibleHeaderVar()
              && var.kind() != VarDefn.Kind.STATE
              && (var.kind() != VarDefn.Kind.PARAM // a soydoc param -> not ij
                  || !((TemplateParam) var).isInjected())) { // an {@param but not {@inject
            shouldEnsureDataIsDefined = true;
            return;
          }
        }
        if (node instanceof CallNode) {
          if (((CallNode) node).isPassingAllData()) {
            shouldEnsureDataIsDefined = true;
            return;
          }
        }
        if (node instanceof ParentNode) {
          for (Node child : ((ParentNode<?>) node).getChildren()) {
            visit(child);
            if (shouldEnsureDataIsDefined) {
              return;
            }
          }
        }
        if (node instanceof ExprHolderNode) {
          for (ExprRootNode expr : ((ExprHolderNode) node).getExprList()) {
            visit(expr);
            if (shouldEnsureDataIsDefined) {
              return;
            }
          }
        }
      }
    }.exec(template);
  }
public boolean exec ( TemplateNode template ) { boolean hasOptional = false ; for ( TemplateParam param : template . getParams ( ) ) { if ( param . isRequired ( ) ) { return false ; } else { hasOptional = true ; } } if ( hasOptional ) { return true ; } return new AbstractNodeVisitor < Node , Boolean > ( ) { boolean shouldEnsureDataIsDefined ; @ Override public Boolean exec ( Node node ) { visit ( node ) ; return shouldEnsureDataIsDefined ; } @ Override public void visit ( Node node ) { if ( node instanceof VarRefNode ) { VarRefNode varRefNode = ( VarRefNode ) node ; VarDefn var = varRefNode . getDefnDecl ( ) ; if ( varRefNode . isPossibleHeaderVar ( ) && var . kind ( ) != VarDefn . Kind . STATE && ( var . kind ( ) != VarDefn . Kind . PARAM || ! ( ( TemplateParam ) var ) . isInjected ( ) ) ) { shouldEnsureDataIsDefined = true ; return ; } } if ( node instanceof CallNode ) { if ( ( ( CallNode ) node ) . isPassingAllData ( ) ) { shouldEnsureDataIsDefined = true ; return ; } } if ( node instanceof ParentNode ) { for ( Node child : ( ( ParentNode < ? > ) node ) . getChildren ( ) ) { visit ( child ) ; if ( shouldEnsureDataIsDefined ) { return ; } } } if ( node instanceof ExprHolderNode ) { for ( ExprRootNode expr : ( ( ExprHolderNode ) node ) . getExprList ( ) ) { visit ( expr ) ; if ( shouldEnsureDataIsDefined ) { return ; } } } } } . exec ( template ) ; }
Runs this pass on the given template.