FEEL spec Table 38
Delegates to {@link InfixOpNode} except evaluationcontext
188915
public static Boolean and(Object left, Object right) {
        return (Boolean) InfixOpNode.and(left, right, null);
    }
29174
private SoyValue eval(ExprNode expr, SoyNode node) {

    if (expr == null) {
      throw RenderException.create("Cannot evaluate expression in V1 syntax.")
          .addStackTraceElement(node);
    }

    // Lazily initialize evalVisitor.
    if (evalVisitor == null) {
      evalVisitor =
          evalVisitorFactory.create(
              env,
              cssRenamingMap,
              xidRenamingMap,
              msgBundle,
              debugSoyTemplateInfo,
              pluginInstances);
    }

    try {
      return evalVisitor.exec(expr);
    } catch (RenderException e) {
      // RenderExceptions can be thrown when evaluating lazy transclusions.
      throw RenderException.createFromRenderException(
          "When evaluating \"" + expr.toSourceString() + "\": " + e.getMessage(), e, node);
    } catch (Exception e) {
      throw RenderException.createWithSource(
          "When evaluating \"" + expr.toSourceString() + "\": " + e.getMessage(), e, node);
    }
  }
585646
@SuppressWarnings("incomplete-switch")
  private ParseTree parseLeftHandSideExpression() {
    SourcePosition start = getTreeStartLocation();
    ParseTree operand = parseNewExpression();

    // this test is equivalent to is member expression
    if (!(operand instanceof NewExpressionTree)
        || ((NewExpressionTree) operand).arguments != null) {

      // The Call expression productions
      while (peekCallSuffix()) {
        switch (peekType()) {
          case OPEN_PAREN:
            ArgumentListTree arguments = parseArguments();
            operand = new CallExpressionTree(getTreeLocation(start), operand, arguments);
            break;
          case OPEN_SQUARE:
            eat(TokenType.OPEN_SQUARE);
            ParseTree member = parseExpression();
            eat(TokenType.CLOSE_SQUARE);
            operand = new MemberLookupExpressionTree(getTreeLocation(start), operand, member);
            break;
          case PERIOD:
            eat(TokenType.PERIOD);
            IdentifierToken id = eatIdOrKeywordAsId();
            operand = new MemberExpressionTree(getTreeLocation(start), operand, id);
            break;
          case NO_SUBSTITUTION_TEMPLATE:
          case TEMPLATE_HEAD:
            operand = parseTemplateLiteral(operand);
            break;
          default:
            throw new AssertionError("unexpected case: " + peekType());
        }
      }
    }
    return operand;
  }
668485
@Override
  protected SoyValue visitFunctionNode(FunctionNode node) {
    Object soyFunction = node.getSoyFunction();
    // Handle nonplugin functions.
    if (soyFunction instanceof BuiltinFunction) {
      BuiltinFunction nonpluginFn = (BuiltinFunction) soyFunction;
      switch (nonpluginFn) {
        case IS_FIRST:
          return visitIsFirstFunction(node);
        case IS_LAST:
          return visitIsLastFunction(node);
        case INDEX:
          return visitIndexFunction(node);
        case CHECK_NOT_NULL:
          return visitCheckNotNullFunction(node.getChild(0));
        case CSS:
          return visitCssFunction(node);
        case XID:
          return visitXidFunction(node);
        case IS_PRIMARY_MSG_IN_USE:
          return visitIsPrimaryMsgInUseFunction(node);
        case V1_EXPRESSION:
          throw new UnsupportedOperationException(
              "the v1Expression function can't be used in templates compiled to Java");
        case TO_FLOAT:
          return visitToFloatFunction(node);
        case DEBUG_SOY_TEMPLATE_INFO:
          return BooleanData.forValue(debugSoyTemplateInfo);
        case VE_DATA:
          return NullData.INSTANCE;
        case MSG_WITH_ID:
        case REMAINDER:
          // should have been removed earlier in the compiler
          throw new AssertionError();
      }
      throw new AssertionError();
    } else if (soyFunction instanceof SoyJavaFunction) {
      List<SoyValue> args = this.visitChildren(node);
      SoyJavaFunction fn = (SoyJavaFunction) soyFunction;
      // Note: Arity has already been checked by CheckFunctionCallsVisitor.
      return computeFunctionHelper(fn, args, node);
    } else if (soyFunction instanceof SoyJavaSourceFunction) {
      List<SoyValue> args = this.visitChildren(node);
      SoyJavaSourceFunction fn = (SoyJavaSourceFunction) soyFunction;
      // Note: Arity has already been checked by CheckFunctionCallsVisitor.
      return computeFunctionHelper(fn, args, node);
    } else if (soyFunction instanceof LoggingFunction) {
      return StringData.forValue(((LoggingFunction) soyFunction).getPlaceholder());
    } else {
      throw RenderException.create(
          "Failed to find Soy function with name '"
              + node.getFunctionName()
              + "'"
              + " (function call \""
              + node.toSourceString()
              + "\").");
    }
  }
49675
public CList parse(UseExtension operationRegister, Properties properties, String infixExpression, Object... values) throws ParseException {
        pUsedExtensions = null;
        this.usedExtensions = operationRegister;
        this.properties = properties;

        return parse(infixExpression, values);
    }
862953
function isContextSensitive(node) {
            ts.Debug.assert(node.kind !== 147 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            switch (node.kind) {
                case 179 /* FunctionExpression */:
                case 180 /* ArrowFunction */:
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 171 /* ObjectLiteralExpression */:
                    return ts.forEach(node.properties, isContextSensitive);
                case 170 /* ArrayLiteralExpression */:
                    return ts.forEach(node.elements, isContextSensitive);
                case 188 /* ConditionalExpression */:
                    return isContextSensitive(node.whenTrue) ||
                        isContextSensitive(node.whenFalse);
                case 187 /* BinaryExpression */:
                    return node.operatorToken.kind === 52 /* BarBarToken */ &&
                        (isContextSensitive(node.left) || isContextSensitive(node.right));
                case 253 /* PropertyAssignment */:
                    return isContextSensitive(node.initializer);
                case 147 /* MethodDeclaration */:
                case 146 /* MethodSignature */:
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 178 /* ParenthesizedExpression */:
                    return isContextSensitive(node.expression);
            }
            return false;
        }
67284
public OperatorTable<T> infixl(
      Parser<? extends BiFunction<? super T, ? super T, ? extends T>> parser, int precedence) {
    ops.add(new Operator(parser, precedence, Associativity.LASSOC));
    return this;
  }
183466
public static void assertXpathEvaluatesTo(QualifiedName expectedValue,
                                              String xpathExpression,
                                              Document inDocument)
        throws XpathException {
        XpathEngine simpleXpathEngine = XMLUnit.newXpathEngine();
        NodeList nl =
            simpleXpathEngine.getMatchingNodes(xpathExpression, inDocument);
        NamespaceContext ctx = null;
        if (nl.getLength() > 0) {
            ctx = new NodeBasedNamespaceContext(nl.item(0));
        }
        assertEquals(expectedValue,
                     QualifiedName
                     .valueOf(simpleXpathEngine.evaluate(xpathExpression,
                                                         inDocument),
                              ctx));
    }
801840
private String getFNSignatureFromIContext(INode node) {

        String ret = node.getNodeData().getName();
        List<INode> children = node.getChildrenList();
        if (children != null && children.size() > 0) {
            ret += "(";
            for (INode aChildren : children) {
                ret += getFNSignatureFromIContext(aChildren) + ",";
            }

            ret = ret.substring(0, ret.length() - 1);
            ret += ")";
        }
        return ret;

    }
334969
private ParseTree parseMemberExpressionNoNew() {
    SourcePosition start = getTreeStartLocation();
    ParseTree operand;
    if (peekAsyncFunctionStart()) {
      operand = parseAsyncFunctionExpression();
    } else if (peekFunction()) {
      operand = parseFunctionExpression();
    } else {
      operand = parsePrimaryExpression();
    }
    while (peekMemberExpressionSuffix()) {
      switch (peekType()) {
        case OPEN_SQUARE:
          eat(TokenType.OPEN_SQUARE);
          ParseTree member = parseExpression();
          eat(TokenType.CLOSE_SQUARE);
          operand = new MemberLookupExpressionTree(
              getTreeLocation(start), operand, member);
          break;
        case PERIOD:
          eat(TokenType.PERIOD);
          IdentifierToken id = eatIdOrKeywordAsId();
          operand = new MemberExpressionTree(getTreeLocation(start), operand, id);
          break;
        case NO_SUBSTITUTION_TEMPLATE:
        case TEMPLATE_HEAD:
          operand = parseTemplateLiteral(operand);
          break;
        default:
          throw new RuntimeException("unreachable");
      }
    }
    return operand;
  }
794230
private static String getPromotionSuffix(Assignment node) {
    if (!needsPromotionSuffix(node.getOperator())) {
      return "";
    }
    TypeKind lhsKind = node.getLeftHandSide().getTypeMirror().getKind();
    TypeKind rhsKind = node.getRightHandSide().getTypeMirror().getKind();
    if (lhsKind == TypeKind.DOUBLE || rhsKind == TypeKind.DOUBLE) {
      return "D";
    }
    if (lhsKind == TypeKind.FLOAT || rhsKind == TypeKind.FLOAT) {
      return "F";
    }
    if (lhsKind == TypeKind.LONG || rhsKind == TypeKind.LONG) {
      return "J";
    }
    return "I";
  }
1273794
private void maybeCollapseIntoForStatements(Node n, Node parent) {
    // Only SCRIPT, BLOCK, and LABELs can have FORs that can be collapsed into.
    // LABELs are not supported here.
    if (parent == null || !NodeUtil.isStatementBlock(parent)) {
      return;
    }

    // Is the current node something that can be in a for loop initializer?
    if (!n.isExprResult() && !n.isVar()) {
      return;
    }

    // Is the next statement a valid FOR?
    Node nextSibling = n.getNext();
    if (nextSibling == null) {
      return;
    } else if (nextSibling.isForIn() || nextSibling.isForOf()) {
      Node forNode = nextSibling;
      Node forVar = forNode.getFirstChild();
      if (forVar.isName()
          && n.isVar() && n.hasOneChild()) {
        Node name = n.getFirstChild();
        if (!name.hasChildren()
            && forVar.getString().equals(name.getString())) {
          // OK, the names match, and the var declaration does not have an
          // initializer. Move it into the loop.
          parent.removeChild(n);
          forNode.replaceChild(forVar, n);
          compiler.reportChangeToEnclosingScope(parent);
        }
      }
    } else if (nextSibling.isVanillaFor() && nextSibling.getFirstChild().isEmpty()) {

      // Does the current node contain an in operator?  If so, embedding
      // the expression in a for loop can cause some JavaScript parsers (such
      // as the PlayStation 3's browser based on Access's NetFront
      // browser) to fail to parse the code.
      // See bug 1778863 for details.
      if (NodeUtil.containsType(n, Token.IN)) {
        return;
      }

      // Move the current node into the FOR loop initializer.
      Node forNode = nextSibling;
      Node oldInitializer = forNode.getFirstChild();
      parent.removeChild(n);

      Node newInitializer;
      if (n.isVar()) {
        newInitializer = n;
      } else {
        // Extract the expression from EXPR_RESULT node.
        checkState(n.hasOneChild(), n);
        newInitializer = n.getFirstChild();
        n.removeChild(newInitializer);
      }

      forNode.replaceChild(oldInitializer, newInitializer);

      compiler.reportChangeToEnclosingScope(forNode);
    }
  }
35656
public void registerPrefixStatsRangePositionValue(String field, String prefix,
      IndexOutput outPrefix) throws IOException {
    initPrefixStatsField(field);
    registerPrefix(field, prefix, outPrefix);
    singlePositionPrefix.get(field).remove(prefix);
    multiplePositionPrefix.get(field).add(prefix);
  }
17974
@Override
  public void visit(final NodeTraversal t, final Node n, final Node p) {
    final JSDocInfo info = n.getJSDocInfo();
    if (info == null) {
      return;
    }
    final JSTypeRegistry registry = compiler.getTypeRegistry();

    final List<Node> thrownTypes =
        transform(
            info.getThrownTypes(),
            new Function<JSTypeExpression, Node>() {
              @Override
              public Node apply(JSTypeExpression expr) {
                return expr.getRoot();
              }
            });

    final Scope scope = t.getScope();
    for (Node typeRoot : info.getTypeNodes()) {
      NodeUtil.visitPreOrder(
          typeRoot,
          new NodeUtil.Visitor() {
            @Override
            public void visit(Node node) {
              if (!node.isString()) {
                return;
              }
              if (thrownTypes.contains(node)) {
                return;
              }
              Node parent = node.getParent();
              if (parent != null) {
                switch (parent.getToken()) {
                  case BANG:
                  case QMARK:
                  case THIS: // The names inside function(this:Foo) and
                  case NEW: // function(new:Bar) are already non-null.
                  case TYPEOF: // Names after 'typeof' don't have nullability.
                    return;
                  case PIPE:
                    { // Inside a union
                      Node gp = parent.getParent();
                      if (gp != null && gp.getToken() == Token.QMARK) {
                        return; // Inside an explicitly nullable union
                      }
                      for (Node child : parent.children()) {
                        if ((child.isString() && child.getString().equals("null"))
                            || child.getToken() == Token.QMARK) {
                          return; // Inside a union that contains null or nullable type
                        }
                      }
                      break;
                    }
                  default:
                    break;
                }
              }
              String typeName = node.getString();
              if (typeName.equals("null") || registry.getType(scope, typeName) == null) {
                return;
              }
              JSType type = registry.createTypeFromCommentNode(node);
              if (type.isNullable()) {
                compiler.report(JSError.make(node, IMPLICITLY_NULLABLE_JSDOC, typeName));
              }
            }
          },
          Predicates.alwaysTrue());
    }
  }
882702
function evaluateTypedParameters(node, msg, param, type) {
        console.log('eval - p:%s, t:%s', param, type);
        let prop;
        if (type === 'jsonata') {
            prop = RED.util.evaluateJSONataExpression(param, msg);
        } else {
            prop = RED.util.evaluateNodeProperty(param, type, node, msg);
        }
        return prop;
    }
141204
private Node initTemplate(Node templateFunctionNode) {
    Node prepped = templateFunctionNode.cloneTree();
    prepTemplatePlaceholders(prepped);

    Node body = prepped.getLastChild();
    Node startNode;
    if (body.hasOneChild() && body.getFirstChild().isExprResult()) {
      // When matching an expression, don't require it to be a complete
      // statement.
      startNode = body.getFirstFirstChild();
    } else {
      startNode = body.getFirstChild();
    }

    for (int i = 0; i < templateLocals.size(); i++) {
      // reserve space in the locals array.
      this.localVarMatches.add(null);
    }
    for (int i = 0; i < templateParams.size(); i++) {
      // reserve space in the params array.
      this.paramNodeMatches.add(null);
    }

    return startNode;
  }
30460
@Override protected void visitPrintNode(PrintNode node) {
    Expression expr = translateExpr(node.getExpr());

    // Process directives.
    for (PrintDirectiveNode directiveNode : node.getChildren()) {

      // Get directive.
      SoyPrintDirective directive = directiveNode.getPrintDirective();
      if (!(directive instanceof SoyJsSrcPrintDirective)) {
        errorReporter.report(
            node.getSourceLocation(), UNKNOWN_SOY_JS_SRC_PRINT_DIRECTIVE, directiveNode.getName());
        return;
      }

      // Get directive args.
      List<ExprRootNode> argNodes = directiveNode.getArgs();

      // Convert args to CodeChunks.
      List<Expression> argChunks = new ArrayList<>(argNodes.size());
      for (ExprRootNode argNode : argNodes) {
        argChunks.add(translateExpr(argNode));
      }

      // Apply directive.
      expr =
          SoyJsPluginUtils.applyDirective(
              expr,
              (SoyJsSrcPrintDirective) directive,
              argChunks,
              node.getSourceLocation(),
              errorReporter);
    }

    chunks.add(expr);
  }