private static JsValue ScalarToRawString(JsValue self2, JsValue[] args) { if (args.Length != 2) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) may be called on with two parameters only"); } JsValue firstParam = args[0]; if (firstParam.IsObject() == false || args[0].AsObject() is BlittableObjectInstance == false) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) may be called with a document first parameter only"); } JsValue secondParam = args[1]; if (args[1].IsObject() == false || secondParam.AsObject() is FunctionInstance == false) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) must be called with a second lambda argument"); } BlittableObjectInstance selfInstance = firstParam.AsObject() as BlittableObjectInstance; FunctionInstance lambda = secondParam.AsObject() as FunctionInstance; //TODO: expose this in Jint directly instead of reflection var funcDeclField = typeof(ScriptFunctionInstance).GetField("_functionDeclaration", BindingFlags.Instance | BindingFlags.NonPublic); var func = (IFunction)funcDeclField.GetValue(lambda); var ret = func.Body.Body.As <ReturnStatement[]>(); if (ret.Length != 1) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must contain a single return expression"); } StaticMemberExpression staticMemberExpression = ret[0].Argument.As <StaticMemberExpression>(); var prop = staticMemberExpression.Property; if (staticMemberExpression.Object is Identifier == false) { throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must contain a single return expression of a single field"); } var propName = prop.As <Identifier>().Name; if (selfInstance.OwnValues.TryGetValue(propName, out var existingValue)) { if (existingValue.Changed) { return(existingValue.Value); } } var propertyIndex = selfInstance.Blittable.GetPropertyIndex(propName); if (propertyIndex == -1) { return(new JsValue(new ObjectInstance(selfInstance.Engine) { Extensible = true })); } BlittableJsonReaderObject.PropertyDetails propDetails = new BlittableJsonReaderObject.PropertyDetails(); selfInstance.Blittable.GetPropertyByIndex(propertyIndex, ref propDetails); var value = propDetails.Value; switch (propDetails.Token & BlittableJsonReaderBase.TypesMask) { case BlittableJsonToken.Null: return(JsValue.Null); case BlittableJsonToken.Boolean: return(new JsValue((bool)propDetails.Value)); case BlittableJsonToken.Integer: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.LazyNumber: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.String: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); case BlittableJsonToken.CompressedString: return(new JsValue(new ObjectWrapper(selfInstance.Engine, value))); default: throw new InvalidOperationException("scalarToRawString(document, lambdaToField) lambda to field must return either raw numeric or raw string types"); } }
public virtual void Visit(StaticMemberExpression expression, TContext context) { VisitExpression(expression.Object, context); VisitExpression(expression.Property, context); }