public void Visit(JsConstantWrapper node) { if (node != null) { var symbol = StartSymbol(node); var isNoIn = m_noIn; m_noIn = false; switch (node.PrimitiveType) { case JsPrimitiveType.Boolean: Output(node.ToBoolean() ? "true" : "false"); break; case JsPrimitiveType.Null: Output("null"); break; case JsPrimitiveType.Number: if (node.Context == null || !node.Context.HasCode || (!node.MayHaveIssues && m_settings.IsModificationAllowed(JsTreeModifications.MinifyNumericLiterals))) { // apply minification to the literal to get it as small as possible Output(NormalizeNumber(node.ToNumber(), node.Context)); } else { // context is not null but we don't want to minify numeric literals. // just use the original literal from the context. Output(node.Context.Code); } break; case JsPrimitiveType.Other: Output(node.Value.ToString()); break; case JsPrimitiveType.String: if (node.Context == null || !node.Context.HasCode) { // escape the string value because we don't have a raw context value // to show anyways Output(InlineSafeString(EscapeString(node.Value.ToString()))); } else if (!m_settings.IsModificationAllowed(JsTreeModifications.MinifyStringLiterals)) { // we don't want to modify the strings at all! Output(node.Context.Code); } else if (node.MayHaveIssues || (m_settings.AllowEmbeddedAspNetBlocks && node.StringContainsAspNetReplacement)) { // we'd rather show the raw string, but make sure it's safe for inlining Output(InlineSafeString(node.Context.Code)); } else { // we'd rather show the escaped string Output(InlineSafeString(EscapeString(node.Value.ToString()))); } break; } MarkSegment(node, null, node.Context); SetContextOutputPosition(node.Context); m_startOfStatement = false; m_noIn = isNoIn; EndSymbol(symbol); } }
private JsConstantWrapper StrictNotEqual(JsConstantWrapper left, JsConstantWrapper right) { JsConstantWrapper newLiteral = null; if (m_parser.Settings.IsModificationAllowed(JsTreeModifications.EvaluateNumericExpressions)) { JsPrimitiveType leftType = left.PrimitiveType; if (leftType == right.PrimitiveType) { // the values are the same type switch (leftType) { case JsPrimitiveType.Null: // null !== null is false newLiteral = new JsConstantWrapper(false, JsPrimitiveType.Boolean, null, m_parser); break; case JsPrimitiveType.Boolean: // compare boolean values newLiteral = new JsConstantWrapper(left.ToBoolean() != right.ToBoolean(), JsPrimitiveType.Boolean, null, m_parser); break; case JsPrimitiveType.String: // compare string ordinally if (left.IsOkayToCombine && right.IsOkayToCombine) { newLiteral = new JsConstantWrapper(string.CompareOrdinal(left.ToString(), right.ToString()) != 0, JsPrimitiveType.Boolean, null, m_parser); } break; case JsPrimitiveType.Number: try { // compare the values // +0 and -0 are treated as "equal" in C#, so we don't need to test them separately. // and NaN is always unequal to everything else, including itself. if (left.IsOkayToCombine && right.IsOkayToCombine) { newLiteral = new JsConstantWrapper(left.ToNumber() != right.ToNumber(), JsPrimitiveType.Boolean, null, m_parser); } } catch (InvalidCastException) { // some kind of casting in ToNumber caused a situation where we don't want // to perform the combination on these operands } break; } } else { // if they aren't the same type, they are not equal newLiteral = new JsConstantWrapper(true, JsPrimitiveType.Boolean, null, m_parser); } } return newLiteral; }
private JsConstantWrapper Divide(JsConstantWrapper left, JsConstantWrapper right) { JsConstantWrapper newLiteral = null; if (left.IsOkayToCombine && right.IsOkayToCombine && m_parser.Settings.IsModificationAllowed(JsTreeModifications.EvaluateNumericExpressions)) { try { double leftValue = left.ToNumber(); double rightValue = right.ToNumber(); double result = leftValue / rightValue; if (JsConstantWrapper.NumberIsOkayToCombine(result)) { newLiteral = new JsConstantWrapper(result, JsPrimitiveType.Number, null, m_parser); } else { if (!left.IsNumericLiteral && JsConstantWrapper.NumberIsOkayToCombine(leftValue)) { left.Parent.ReplaceChild(left, new JsConstantWrapper(leftValue, JsPrimitiveType.Number, left.Context, m_parser)); } if (!right.IsNumericLiteral && JsConstantWrapper.NumberIsOkayToCombine(rightValue)) { right.Parent.ReplaceChild(right, new JsConstantWrapper(rightValue, JsPrimitiveType.Number, right.Context, m_parser)); } } } catch (InvalidCastException) { // some kind of casting in ToNumber caused a situation where we don't want // to perform the combination on these operands } } return newLiteral; }
private JsConstantWrapper LessThanOrEqual(JsConstantWrapper left, JsConstantWrapper right) { JsConstantWrapper newLiteral = null; if (m_parser.Settings.IsModificationAllowed(JsTreeModifications.EvaluateNumericExpressions)) { if (left.IsStringLiteral && right.IsStringLiteral) { if (left.IsOkayToCombine && right.IsOkayToCombine) { // do a straight ordinal comparison of the strings newLiteral = new JsConstantWrapper(string.CompareOrdinal(left.ToString(), right.ToString()) <= 0, JsPrimitiveType.Boolean, null, m_parser); } } else { try { // either one or both are NOT a string -- numeric comparison if (left.IsOkayToCombine && right.IsOkayToCombine) { newLiteral = new JsConstantWrapper(left.ToNumber() <= right.ToNumber(), JsPrimitiveType.Boolean, null, m_parser); } } catch (InvalidCastException) { // some kind of casting in ToNumber caused a situation where we don't want // to perform the combination on these operands } } } return newLiteral; }