The Labs \ Source Viewer \ SSCLI \ Microsoft.JScript \ In

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. namespace Microsoft.JScript
  16. {
  17.    
  18.     using System;
  19.     using System.Collections;
  20.     using System.Reflection;
  21.     using System.Reflection.Emit;
  22.     using System.Runtime.InteropServices.Expando;
  23.    
  24.     public sealed class In : BinaryOp
  25.     {
  26.        
  27.         internal In(Context context, AST operand1, AST operand2) : base(context, operand1, operand2)
  28.         {
  29.         }
  30.        
  31.         internal override object Evaluate()
  32.         {
  33.             object v1 = this.operand1.Evaluate();
  34.             object v2 = this.operand2.Evaluate();
  35.             try {
  36.                 return JScriptIn(v1, v2);
  37.             }
  38.             catch (JScriptException e) {
  39.                 if (e.context == null)
  40.                     e.context = this.operand2.context;
  41.                 throw e;
  42.             }
  43.         }
  44.        
  45.         internal override IReflect InferType(JSField inference_target)
  46.         {
  47.             return Typeob.Boolean;
  48.         }
  49.        
  50.         //"x in y" should return true whenever "for (var z in y) if (z === x) return true" returns true
  51.         public static bool JScriptIn(object v1, object v2)
  52.         {
  53.             bool result = false;
  54.             if (v2 is ScriptObject)
  55.                 return !(((ScriptObject)v2).GetMemberValue(Convert.ToString(v1)) is Missing);
  56.             else if (v2 is Array) {
  57.                 Array arr = (Array)v2;
  58.                 double d = Convert.ToNumber(v1);
  59.                 int i = (int)d;
  60.                 return d == i && arr.GetLowerBound(0) <= i && i <= arr.GetUpperBound(0);
  61.             }
  62.             else if (v2 is IEnumerable) {
  63.                 if (v1 == null)
  64.                     return false;
  65.                 //Do not enumerate when a direct lookup is available
  66.                 if (v2 is IDictionary)
  67.                     return ((IDictionary)v2).Contains(v1);
  68.                 if (v2 is IExpando) {
  69.                     MemberInfo[] members = ((IReflect)v2).GetMember(Convert.ToString(v1), BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
  70.                     return members.Length > 0;
  71.                 }
  72.                 IEnumerator enu = ((IEnumerable)v2).GetEnumerator();
  73.                 while (!result && enu.MoveNext())
  74.                     if (v1.Equals(enu.Current))
  75.                         return true;
  76.             }
  77.             else if (v2 is IEnumerator) {
  78.                 if (v1 == null)
  79.                     return false;
  80.                 IEnumerator enu = (IEnumerator)v2;
  81.                 while (!result && enu.MoveNext())
  82.                     if (v1.Equals(enu.Current))
  83.                         return true;
  84.             }
  85.             throw new JScriptException(JSError.ObjectExpected);
  86.         }
  87.        
  88.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  89.         {
  90.             this.operand1.TranslateToIL(il, Typeob.Object);
  91.             this.operand2.TranslateToIL(il, Typeob.Object);
  92.             il.Emit(OpCodes.Call, CompilerGlobals.jScriptInMethod);
  93.             Convert.Emit(this, il, Typeob.Boolean, rtype);
  94.         }
  95.        
  96.     }
  97. }

Developer Fusion