Compute the expected type of the given expression.

@param expr the expression.
@return the expected type of the argument.
964190
protected LightweightTypeReference getExpectedType(XExpression expr) {
		final IResolvedTypes resolvedTypes = getTypeResolver().resolveTypes(expr);
		final LightweightTypeReference actualType = resolvedTypes.getActualType(expr);
		return actualType;
	}
142191
private AbstractExpression optimizeInExpressions(AbstractExpression expr) {
        ExpressionType exprType = expr.getExpressionType();
        if (ExpressionType.CONJUNCTION_AND == exprType || ExpressionType.CONJUNCTION_OR == exprType) {
            AbstractExpression optimizedLeft = optimizeInExpressions(expr.getLeft());
            expr.setLeft(optimizedLeft);
            AbstractExpression optimizedRight = optimizeInExpressions(expr.getRight());
            expr.setRight(optimizedRight);
            return expr;
        }

        if (ExpressionType.COMPARE_EQUAL != exprType) {
            return expr;
        }

        assert(expr instanceof ComparisonExpression);
        if (((ComparisonExpression)expr).getQuantifier() != QuantifierType.ANY) {
            return expr;
        }

        /*
         * Verify that an IN expression can be safely converted to an EXISTS one
         * IN (SELECT" forms e.g. "(A, B) IN (SELECT X, Y, FROM ...) =>
         * EXISTS (SELECT 42 FROM ... AND|WHERE|HAVING A=X AND|WHERE|HAVING B=Y)
         */
        AbstractExpression inColumns = expr.getLeft();
        if (inColumns instanceof SelectSubqueryExpression) {
            // If the left child is a (SELECT ...) expression itself we can't convert it
            // to the EXISTS expression because the mandatory run time scalar check -
            // (expression must return a single row at most)
            return expr;
        }

        // The right hand operand of the equality operation must be a SELECT statement
        AbstractExpression rightExpr = expr.getRight();
        if (!(rightExpr instanceof SelectSubqueryExpression)) {
            return expr;
        }

        SelectSubqueryExpression subqueryExpr = (SelectSubqueryExpression) rightExpr;
        AbstractParsedStmt subquery = subqueryExpr.getSubqueryStmt();
        if (!(subquery instanceof ParsedSelectStmt)) {
            return expr;
        }

        ParsedSelectStmt selectStmt = (ParsedSelectStmt) subquery;

        // Must not have OFFSET or LIMIT set
        // EXISTS (select * from T where T.X = parent.X order by T.Y offset 10 limit 5)
        //      seems to require 11 matches
        // parent.X IN (select T.X from T order by T.Y offset 10 limit 5)
        //      seems to require 1 match that has exactly 10-14 rows (matching or not) with lesser or equal values of Y.
        if (selectStmt.hasLimitOrOffset()) {
            return expr;
        }

        ParsedSelectStmt.rewriteInSubqueryAsExists(selectStmt, inColumns);
        subqueryExpr.resolveCorrelations();
        AbstractExpression existsExpr = new OperatorExpression();
        existsExpr.setExpressionType(ExpressionType.OPERATOR_EXISTS);
        existsExpr.setLeft(subqueryExpr);
        return optimizeExistsExpression(existsExpr);
    }
1081635
public static List<String> parse(String expr) {
        
        List<String> expressions = new ArrayList<>();
        
        int parenthesis = 0; // '(' and ')'
        int brackets = 0; // '{' and '}'
        int brackets2 = 0; // '[' and ']'

        String[] lines = expr.split("\n");
        StringBuilder sb = new StringBuilder();
        for(String line : lines) {
            line = line.trim();
            if(line.startsWith("#")) {
                // Ignore commented lines
            } else {
                char currentChar=0;
                for (int i = 0; i < line.length(); i++) {
                    currentChar = line.charAt(i);
                    if (currentChar == '#') {// Ignore rest of line
                        line = line.substring(0,i);
                        break; 
                    } else if (currentChar == '(') {
                        parenthesis++;
                    } else if (currentChar == ')') {
                        parenthesis--;
                    } else if (currentChar == '{') {
                        brackets++;
                    } else if (currentChar == '}') {
                        brackets--;
                    } else if (currentChar == '[') {
                        brackets2++;
                    } else if (currentChar == ']') {
                        brackets2--;
                    } else if (parenthesis == 0 && brackets == 0 && brackets2 == 0) {
                        if(currentChar == ';') {
                            String firstLine = line.substring(0, i+1);
                            sb.append(firstLine);                            
                            expressions.add(sb.toString());
                            sb = new StringBuilder();
                                                        
                            String remainder = line.substring(i+1);
                            line = remainder.trim()+"\n";
                            i=0;
                        }
                    }
                }
                if(line.trim().length()>0) {
                    sb.append(line);
                    if(parenthesis == 0 && brackets == 0 && brackets2 == 0) {
                        expressions.add(sb.toString());
                        sb = new StringBuilder();
                    } else {
                        if (currentChar!=',' && currentChar!='+' && currentChar!='-' && currentChar!='*' &&currentChar!='/' &&currentChar!='=')
                        sb.append(";\n");
                    }
                }
            }
        }
        
        return expressions;
    }
1209487
private boolean validRawTypeOfTypeExpression(Node expr) {
    // The expression must have two children. The rawTypeOf keyword and the
    // parameter
    if (!checkParameterCount(expr, Keywords.RAWTYPEOF)) {
      return false;
    }
    // The parameter must be a valid type expression
    if (!validTypeTransformationExpression(getCallArgument(expr, 0))) {
      warnInvalidInside(Keywords.RAWTYPEOF.name, expr);
      return false;
    }
    return true;
  }
48155
public static <T extends Number & Comparable<?>> NumberExpression<T> asNumber(Expression<T> expr) {
        Expression<T> underlyingMixin = ExpressionUtils.extract(expr);
        if (underlyingMixin instanceof PathImpl) {
            return new NumberPath<T>((PathImpl<T>) underlyingMixin);
        } else if (underlyingMixin instanceof OperationImpl) {
            return new NumberOperation<T>((OperationImpl<T>) underlyingMixin);
        } else if (underlyingMixin instanceof TemplateExpressionImpl) {
            return new NumberTemplate<T>((TemplateExpressionImpl<T>) underlyingMixin);
        } else {
            return new NumberExpression<T>(underlyingMixin) {

                private static final long serialVersionUID = -8712299418891960222L;

                @Override
                public <R, C> R accept(Visitor<R, C> v, C context) {
                    return this.mixin.accept(v, context);
                }

            };
        }
    }
13295
function (expression, types) {
        var args = types.split(" | "),
            i, len, found = false;

        for (i=0, len=args.length; i < len && !found && expression.hasNext(); i++) {
            found = this.isType(expression, args[i]);
        }

        return found;
    }
692259
private ExprKraken parseAddExpr()
  {
    ExprKraken left = parseMulExpr();

    while (true) {
      Token token = scanToken();

      switch (token) {
      case PLUS:
        left = new BinaryExpr(BinaryOp.ADD, left, parseSimpleTerm());
        break;
      case MINUS:
        left = new BinaryExpr(BinaryOp.SUB, left, parseSimpleTerm());
        break;

      default:
        _token = token;
        return left;
      }
    }
  }
514303
public Expression create(String expression, ExpressionType expressionType) {
        return create(expression, expressionType, null);
    }
1323740
private Boolean getKnownValue(Expression expr) {
    Object value = expr.getConstantValue();
    if (value instanceof Boolean) {
      return (Boolean) value;
    }
    switch (expr.getKind()) {
      case BOOLEAN_LITERAL:
        return ((BooleanLiteral) expr).booleanValue();
      case INFIX_EXPRESSION:
        {
          InfixExpression infixExpr = (InfixExpression) expr;
          InfixExpression.Operator op = infixExpr.getOperator();
          if (op == CONDITIONAL_AND || op == CONDITIONAL_OR) {
            // We assume that this node has already been visited and pruned so
            // if it has a known value, it will be equal to the last operand.
            List<Expression> operands = infixExpr.getOperands();
            Boolean lastOperand = getKnownValue(operands.get(operands.size() - 1));
            if (lastOperand != null && lastOperand.booleanValue() == (op == CONDITIONAL_OR)) {
              return lastOperand;
            }
          }
          return null;
        }
      case PARENTHESIZED_EXPRESSION:
        return getKnownValue(((ParenthesizedExpression) expr).getExpression());
      default:
        return null;
    }
  }
289205
public static AbstractExpression evaluateExpression(AbstractExpression expr) {
        if (expr == null) {
            return null;
        }

        // Evaluate children first
        expr.setLeft(evaluateExpression(expr.getLeft()));
        expr.setRight(evaluateExpression(expr.getRight()));

        // Evaluate self
        if (ExpressionType.CONJUNCTION_AND == expr.getExpressionType()) {
            if (ExpressionType.VALUE_CONSTANT == expr.getLeft().getExpressionType()) {
                if (ConstantValueExpression.isBooleanTrue(expr.getLeft())) {
                    return expr.getRight();
                } else {
                    return expr.getLeft();
                }
            }
            if (ExpressionType.VALUE_CONSTANT == expr.getRight().getExpressionType()) {
                if (ConstantValueExpression.isBooleanTrue(expr.getRight())) {
                    return expr.getLeft();
                } else {
                    return expr.getRight();
                }
            }
        } else if (ExpressionType.CONJUNCTION_OR == expr.getExpressionType()) {
            if (ExpressionType.VALUE_CONSTANT == expr.getLeft().getExpressionType()) {
                if (ConstantValueExpression.isBooleanTrue(expr.getLeft())) {
                    return expr.getLeft();
                } else {
                    return expr.getRight();
                }
            }
            if (ExpressionType.VALUE_CONSTANT == expr.getRight().getExpressionType()) {
                if (ConstantValueExpression.isBooleanTrue(expr.getRight())) {
                    return expr.getRight();
                } else {
                    return expr.getLeft();
                }
            }
        } else if (ExpressionType.OPERATOR_NOT == expr.getExpressionType()) {
            AbstractExpression leftExpr = expr.getLeft();
            // function expressions can also return boolean. So the left child expression
            // can be expression which are not constant value expressions, so don't
            // evaluate every left child expr as constant value expression
            if ((VoltType.BOOLEAN == leftExpr.getValueType()) &&
                    (leftExpr instanceof ConstantValueExpression)) {
                if (ConstantValueExpression.isBooleanTrue(leftExpr)) {
                    return ConstantValueExpression.getFalse();
                } else {
                    return ConstantValueExpression.getTrue();
                }
            } else if (ExpressionType.OPERATOR_NOT == leftExpr.getExpressionType()) {
                return leftExpr.getLeft();
            } else if (ExpressionType.CONJUNCTION_OR == leftExpr.getExpressionType()) {
                // NOT (.. OR .. OR ..) => NOT(..) AND NOT(..) AND NOT(..)
                AbstractExpression l = new OperatorExpression(ExpressionType.OPERATOR_NOT, leftExpr.getLeft(), null);
                AbstractExpression r = new OperatorExpression(ExpressionType.OPERATOR_NOT, leftExpr.getRight(), null);
                leftExpr = new OperatorExpression(ExpressionType.CONJUNCTION_AND, l, r);
                return evaluateExpression(leftExpr);
            }
            // NOT (expr1 AND expr2) => (NOT expr1) || (NOT expr2)
            // The above case is probably not interesting to do for short circuit purpose
        }
        return expr;
    }
855767
public static boolean isFunctionOfType(Expression expr, FunctionDefinition.Type type) {
		return expr instanceof CallExpression &&
			((CallExpression) expr).getFunctionDefinition().getType() == type;
	}
658808
private boolean validUnionTypeExpression(Node expr) {
    // The expression must have at least three children: The union keyword and
    // two type expressions
    if (!checkParameterCount(expr, Keywords.UNION)) {
      return false;
    }
    int paramCount = getCallParamCount(expr);
    // Check if each of the members of the union is a valid type expression
    for (int i = 0; i < paramCount; i++) {
      if (!validTypeTransformationExpression(getCallArgument(expr, i))) {
        warnInvalidInside("union type", expr);
        return false;
      }
    }
    return true;
  }
549510
public static ExprInt toExprInt(Expression expr) {
	if (expr instanceof ExprInt) return (ExprInt) expr;
	if (expr instanceof Literal) {
	    Double dbl = ((Literal) expr).getDouble(null);
	    if (dbl != null) return expr.getFactory().createLitInteger((int) dbl.doubleValue(), expr.getStart(), expr.getEnd());
	}
	return new CastInt(expr);
    }
667671
public function getType($expr)
	{
		$match = $this->getMatch($expr);

		return (isset($match, $this->matchGroup[$match[0]])) ? $this->matchGroup[$match[0]] : null;
	}
1138599
private void unbox(Expression expr, PrimitiveType primitiveType) {
    TypeElement boxedClass = findBoxedSuperclass(expr.getTypeMirror());
    if (primitiveType == null && boxedClass != null) {
      primitiveType = typeUtil.unboxedType(boxedClass.asType());
    }
    if (primitiveType == null) {
      return;
    }
    ExecutableElement valueMethod = ElementUtil.findMethod(
        boxedClass, TypeUtil.getName(primitiveType) + VALUE_METHOD);
    assert valueMethod != null : "could not find value method for " + boxedClass;
    MethodInvocation invocation = new MethodInvocation(new ExecutablePair(valueMethod), null);
    expr.replaceWith(invocation);
    invocation.setExpression(expr);
  }
208004
public static Pattern compilePattern(final String expr) {
        Pattern pattern;
        final int lastChar = expr.length() - 1;
        if (expr.charAt(0) == '/' && expr.charAt(lastChar) == '/') {
            pattern = Pattern.compile(expr.substring(1, lastChar));
        } else {
            pattern = Pattern.compile(Pattern.quote(expr));
        }
        return pattern;
    }
894596
private BigInteger evalUnaryExpression(AstNode exprAst) {
    // only 'unary-operator cast-expression' production is allowed in #if-context

    AstNode operator = exprAst.getFirstChild();
    AstNode operand = operator.getNextSibling();
    AstNodeType operatorType = operator.getFirstChild().getType();

    if (operatorType.equals(CppPunctuator.PLUS)) {
      return evalToInt(operand);
    } else if (operatorType.equals(CppPunctuator.MINUS)) {
      return evalToInt(operand).negate();
    } else if (operatorType.equals(CppPunctuator.NOT)) {
      boolean result = !evalToBoolean(operand);
      return result ? BigInteger.ONE : BigInteger.ZERO;
    } else if (operatorType.equals(CppPunctuator.BW_NOT)) {
      //todo: need more information (signed/unsigned, data type length) to invert bits in all cases correct
      return evalToInt(operand).not().and(UINT64_MAX);
    } else {
      throw new EvaluationException("Unknown unary operator  '" + operatorType + "'");
    }
  }