public Value evaluate()

in modules/asc/src/java/macromedia/asc/embedding/LintEvaluator.java [1107:1245]


	public Value evaluate( Context cx, BinaryExpressionNode node )
	{
		Value  lhsType = null;
		Value  rhsType = null;

		if (first_pass)
		{
			if (node.lhs != null)
				node.lhs.evaluate(cx,this);
			if (node.rhs != null)
				node.rhs.evaluate(cx,this);
			return (node.slot != null) ? node.slot.getType().getTypeValue() : cx.voidType();
		}

		if( node.lhs != null)
			lhsType = node.lhs.evaluate(cx,this); // do lhs first, then potentially modify operand, then rhs.  Output buffer can't back up

		switch( node.op )
		{
            case LESSTHAN_TOKEN:
            case GREATERTHAN_TOKEN:
            case LESSTHANOREQUALS_TOKEN:
            case GREATERTHANOREQUALS_TOKEN:
			case STRICTEQUALS_TOKEN:
			case STRICTNOTEQUALS_TOKEN:
			case EQUALS_TOKEN:
			case NOTEQUALS_TOKEN:
				if( node.rhs != null)
					rhsType = node.rhs.evaluate(cx,this);

  				// if lhsType or rhsType is void, it means its the result of an undefined prop access or function call
  				//  Don't warn twice about it.
  				if ( (lhsType != rhsType) && (lhsType != cx.voidType()) && (rhsType != cx.voidType()) )
  				{
  					if ( (lhsType == undefinedLiteral && rhsType != cx.noType()) ||
  							  (lhsType != cx.noType() && rhsType == undefinedLiteral) )
  					{
  						String typeName = (lhsType == undefinedLiteral ? getSimpleTypeName((TypeValue )rhsType)
  							: getSimpleTypeName((TypeValue )lhsType));
  						warning(node.getPosition(), cx.input,  kWarning_BadUndefinedComparision, typeName, typeName);
  					}
  					else if ( (lhsType == cx.nullType()) || (rhsType == cx.nullType()) )
 					{
  						TypeValue nonVoidType = (lhsType == cx.nullType() ? (TypeValue)rhsType : (TypeValue)lhsType);

  						switch( nonVoidType.getTypeId() )
  						{
  							case TYPE_boolean:
  							case TYPE_int:
  							case TYPE_uint:
  							case TYPE_double:
  							case TYPE_decimal:
  								warning(node.getPosition(), cx.input, kWarning_BadNullComparision, getSimpleTypeName(nonVoidType));
  								break;
  						}
  					}
  				}
                if (lhsType == cx.doubleType() || (cx.statics.es4_numerics && (lhsType == cx.decimalType())))
 				{
 					MemberExpressionNode mem = (node.lhs instanceof MemberExpressionNode) ? (MemberExpressionNode)(node.lhs) : null;
 					if (mem != null)
 					{
 						GetExpressionNode getter = (mem.selector instanceof GetExpressionNode) ? (GetExpressionNode)(mem.selector) : null;
 						if (getter != null && "NaN".equals(getter.ref.name))
 							warning(node.getPosition(), cx.input, kWarning_BadNaNComparision);
 					}
 				}
 				if (rhsType == cx.doubleType() || (cx.statics.es4_numerics && (lhsType == cx.decimalType())))
 				{
					MemberExpressionNode mem = (node.rhs instanceof MemberExpressionNode) ? (MemberExpressionNode)(node.rhs) : null;
					if (mem != null)
					{
						GetExpressionNode getter = (mem.selector instanceof GetExpressionNode) ? (GetExpressionNode)(mem.selector) : null;
						if (getter != null && "NaN".equals(getter.ref.name))
							warning(node.getPosition(), cx.input, kWarning_BadNaNComparision);
					}
				}

				break;

			case INSTANCEOF_TOKEN:
			    // yes, I do mean position-11; we don't know the position of the word instanceof
			    // so we start from rhs and go back 11 spaces
			    warning(node.rhs.getPosition() - 11, cx.input, kWarning_InstanceOfChanges);
                if( node.rhs != null )
					node.rhs.evaluate(cx,this);
				break;

			case MULT_TOKEN:
			case DIV_TOKEN:
			case MODULUS_TOKEN:
			case MINUS_TOKEN:

			case LEFTSHIFT_TOKEN:
			case RIGHTSHIFT_TOKEN:
			case UNSIGNEDRIGHTSHIFT_TOKEN:

			case BITWISEAND_TOKEN:
			case BITWISEXOR_TOKEN:
			case BITWISEOR_TOKEN:
			case LOGICALAND_TOKEN:
			case LOGICALOR_TOKEN:
                if( node.rhs != null )
                      rhsType = node.rhs.evaluate(cx,this);

                if (lhsType == cx.functionType())
                {
                    if (node.lhs instanceof MemberExpressionNode)
                    {
                        MemberExpressionNode memb = (MemberExpressionNode)(node.lhs);
                        String funcName = memb.ref.name;
                        warning(node.lhs.pos(), cx.input, kWarning_UnlikelyFunctionValue, cx.objectType().toString(),
                                funcName);
                    }
                }
                 if (rhsType == cx.functionType())
                {
                    if (node.rhs instanceof MemberExpressionNode)
                    {
                        MemberExpressionNode memb = (MemberExpressionNode)(node.rhs);
                        String funcName = memb.ref.name;
                        warning(node.rhs.pos(), cx.input, kWarning_UnlikelyFunctionValue, cx.objectType().toString(),
                                funcName);
                    }
                }
                break;

			case PLUS_TOKEN:
            case IN_TOKEN:
            default:
                if( node.rhs != null )
                    rhsType = node.rhs.evaluate(cx,this);
                break;
        }

		// Return the result type of the slot
		return (node.slot!= null) ? node.slot.getType().getTypeValue() : cx.voidType();

	}