public void Visit(MemberExpression expression) { if (expression.Previous != null) { expression.Previous.Accept(this); Builder.Append("."); } expression.Member.Accept(this); }
public void Assign(MemberExpression left, JsInstance value) { string propertyName; Descriptor d = null; if (!(left.Member is IAssignable)) { throw new JintException("The left member of an assignment must be a member"); } EnsureIdentifierIsDefined(value); JsDictionaryObject baseObject; if (left.Previous != null) { // if this a property left.Previous.Accept(this); baseObject = Result as JsDictionaryObject; if (baseObject == null) throw new JintException("Attempt to assign to an undefined variable."); } else { baseObject = CurrentScope; // this a variable propertyName = ((Identifier)left.Member).Text; CurrentScope.TryGetDescriptor(propertyName, out d); } // now baseObject contains an object or a scope against which to resolve left.Member if (left.Member is Identifier) { propertyName = ((Identifier)left.Member).Text; // Assigning function Name //if (value.Class == JsInstance.CLASS_FUNCTION) // ((JsFunction)value).Name = propertyName; Result = baseObject[propertyName] = value; } else { Indexer indexer = left.Member as Indexer; // calculate index expression indexer.Index.Accept(this); if (baseObject is JsObject) { JsObject target = baseObject as JsObject; if (target.Indexer != null) { target.Indexer.set(target, Result, value); Result = value; return; } } // Assigning function Name //if (value.Class == JsInstance.CLASS_FUNCTION) // ((JsFunction)value).Name = Result.Value.ToString(); Result = baseObject[Result] = value; } }
public void Visit(AssignmentExpression statement) { switch (statement.AssignmentOperator) { case AssignmentOperator.Assign: statement.Right.Accept(this); break; case AssignmentOperator.Multiply: new BinaryExpression(BinaryExpressionType.Times, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.Divide: new BinaryExpression(BinaryExpressionType.Div, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.Modulo: new BinaryExpression(BinaryExpressionType.Modulo, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.Add: new BinaryExpression(BinaryExpressionType.Plus, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.Substract: new BinaryExpression(BinaryExpressionType.Minus, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.ShiftLeft: new BinaryExpression(BinaryExpressionType.LeftShift, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.ShiftRight: new BinaryExpression(BinaryExpressionType.RightShift, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.UnsignedRightShift: new BinaryExpression(BinaryExpressionType.UnsignedRightShift, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.And: new BinaryExpression(BinaryExpressionType.BitwiseAnd, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.Or: new BinaryExpression(BinaryExpressionType.BitwiseOr, statement.Left, statement.Right).Accept(this); break; case AssignmentOperator.XOr: new BinaryExpression(BinaryExpressionType.BitwiseXOr, statement.Left, statement.Right).Accept(this); break; default: throw new NotSupportedException(); } JsInstance right = Result; MemberExpression left = statement.Left as MemberExpression; if (left == null) { left = new MemberExpression(statement.Left, null); } Assign(left, right); Result = right; }
public void Visit(MemberExpression expression) { if (expression.Previous != null) { // the previous part is an property, it will set a callTarget expression.Previous.Accept(this); } expression.Member.Accept(this); // Try to evaluate a CLR type if (Result == JsUndefined.Instance && typeFullname.Length > 0) { EnsureClrAllowed(); Type type = typeResolver.ResolveType(typeFullname.ToString()); if (type != null) { Result = Global.WrapClr(type); typeFullname = new StringBuilder(); } } }
public void Assign(MemberExpression left, JsInstance value) { string propertyName; Descriptor d = null; if (!(left.Member is IAssignable)) { throw new JintException("The left member of an assignment must be a member"); } if (left.Previous != null) { left.Previous.Accept(this); if (!(Result is JsDictionaryObject)) { throw new JintException("Attempt to assign to an undefined variable."); } } else { // resolve which CurrentScope to use propertyName = ((Identifier)left.Member).Text; Result = GlobalScope; foreach (JsDictionaryObject scope in Scopes.ToArray()) { if (scope != GlobalScope && scope.TryGetDescriptor(propertyName, out d)) { Result = scope; break; } } } if (left.Member is Identifier) { propertyName = ((Identifier)left.Member).Text; } else { JsInstance temp = Result; Indexer indexer = left.Member as Indexer; indexer.Index.Accept(this); // The left member might be a CLR instance if (temp.IsClr) { if (temp.Value.GetType().IsArray) { Array array = (Array)temp.Value; array.SetValue(Convert.ChangeType(value.Value, array.GetType().GetElementType()), (int)Result.ToNumber()); return; } else // Search custom indexer { // Converts to CLR objects var parameters = JsClr.ConvertParameters(Result, value); PropertyInfo pi = propertyGetter.GetValue(temp.Value, "Item", parameters); if (pi != null) { pi.GetSetMethod().Invoke(temp.Value, parameters); Result = Global.ObjectClass.New(temp.Value); return; } } } propertyName = Result.Value.ToString(); Result = temp; } if (!(Result is JsDictionaryObject)) { throw new JintException("The property is not valid in the current context: " + propertyName); } if (d == null) d = ((JsDictionaryObject)Result).GetDescriptor(propertyName); //Assigning function Name if (value.Class == JsFunction.TYPEOF) ((JsFunction)value).Name = propertyName; // Assignment to Clr property //if (Result.IsClr) //{ // var parameters = JsClr.ConvertParameters(value); // var pi = propertyGetter.GetValue(Result.Value, propertyName); // if (pi != null) // { // var setMethod = pi.GetSetMethod(); // methodInvoker.GetAppropriateParameters(parameters, setMethod.GetParameters(), Result.Value); // setMethod.Invoke(Result.Value, parameters); // } // else // { // var fi = fieldGetter.GetValue(Result.Value, propertyName); // if (fi != null) // { // methodInvoker.GetAppropriateParameters(parameters, new Type[] { fi.FieldType }, Result.Value); // fi.SetValue(Result.Value, parameters[0]); // } // } //} JsDictionaryObject oldCallTarget = callTarget; callTarget = (JsDictionaryObject)Result; JsDictionaryObject target = callTarget; //Descriptor d = target.GetDescriptor(propertyName); if (d != null && (d.DescriptorType != DescriptorType.Value || (d.Owner.Class != JsScope.TYPEOF && (d.DescriptorType == DescriptorType.Value && !d.Owner.IsPrototypeOf(target))) || d.Owner.Class == JsArguments.TYPEOF)) d.Set(target, value); else { if (target.Class == JsFunction.TYPEOF) target = ((JsFunction)target).Scope; target.DefineOwnProperty(propertyName, value); } callTarget = oldCallTarget; }
public void Visit(MemberExpression expression) { bool enterScope = false; if (expression.Previous != null) { expression.Previous.Accept(this); enterScope = Result is JsDictionaryObject;// && !(Result is JsCallFunction); // && !(Result is JsFunction && CurrentScope is JsFunction); // if a function inside a function (closure) then don't enter scope //if (Result == JsUndefined.Instance && System.Diagnostics.Debugger.IsAttached) // System.Diagnostics.Debugger.Break(); if (enterScope) { EnterScope((JsDictionaryObject)Result); } } try { expression.Member.Accept(this); callTarget = null; #region Retain member if result is a function if (Result != null && Result.Class == JsFunction.TYPEOF) { callTarget = CurrentScope; } if (Result != null && Result.Class == JsClrMethodInfo.TYPEOF) { callTarget = CurrentScope; } #endregion // Try to evaluate a CLR type if (Result == JsUndefined.Instance && typeFullname.Length > 0) { EnsureClrAllowed(); Type type = typeResolver.ResolveType(typeFullname.ToString()); if (type != null) { Result = Global.WrapClr(type); } } } finally { if (enterScope) { ExitScope(); } } }
void Analyze(MemberExpression Stmt) { SetCurrentLineAndCharNos(Stmt); if (Stmt.Previous != null) Analyze(Stmt.Previous); if (Stmt.Member != null) Analyze(Stmt.Member); }
public void Visit(MemberExpression expression) { if (expression.Previous != null) { // the previous part is an property, it will set a callTarget expression.Previous.Accept(this); } expression.Member.Accept(this); // Try to evaluate a CLR type if (Result == JsUndefined.Instance && typeFullname.Length > 0) { throw new NotSupportedException(); } }