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

  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.Reflection;
  20.     using System.Diagnostics;
  21.     using System.Security;
  22.     using System.Security.Permissions;
  23.    
  24.     internal sealed class WithObject : ScriptObject, IActivationObject
  25.     {
  26.         internal object contained_object;
  27.         internal bool isKnownAtCompileTime;
  28.         private bool isSuperType;
  29.        
  30.         internal WithObject(ScriptObject parent, object contained_object) : this(parent, contained_object, false)
  31.         {
  32.         }
  33.        
  34.         internal WithObject(ScriptObject parent, object contained_object, bool isSuperType) : base(parent)
  35.         {
  36.             this.contained_object = contained_object;
  37.             this.isKnownAtCompileTime = contained_object is Type || (contained_object is ClassScope && ((ClassScope)contained_object).noExpando) || (contained_object is JSObject && ((JSObject)contained_object).noExpando);
  38.             this.isSuperType = isSuperType;
  39.         }
  40.        
  41.         public object GetDefaultThisObject()
  42.         {
  43.             return this.contained_object;
  44.         }
  45.        
  46.         public FieldInfo GetField(string name, int lexLevel)
  47.         {
  48.             if (lexLevel <= 0)
  49.                 return null;
  50.             IReflect ir;
  51.             if (this.contained_object is IReflect)
  52.                 ir = (IReflect)(this.contained_object);
  53.             else
  54.                 ir = (IReflect)(Globals.TypeRefs.ToReferenceContext(this.contained_object.GetType()));
  55.             FieldInfo field = ir.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.Public);
  56.             if (field != null)
  57.                 return new JSWrappedField(field, this.contained_object);
  58.             PropertyInfo prop = ir.GetProperty(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
  59.             if (prop != null)
  60.                 return new JSPropertyField(prop, this.contained_object);
  61.             if (this.parent != null && lexLevel > 1) {
  62.                 field = ((IActivationObject)this.parent).GetField(name, lexLevel - 1);
  63.                 if (field != null)
  64.                     return new JSWrappedField(field, this.parent);
  65.             }
  66.             return null;
  67.         }
  68.        
  69.         public GlobalScope GetGlobalScope()
  70.         {
  71.             return ((IActivationObject)this.GetParent()).GetGlobalScope();
  72.         }
  73.        
  74.         FieldInfo IActivationObject.GetLocalField(string name)
  75.         {
  76.             Debug.Assert(false);
  77.             return null;
  78.         }
  79.        
  80.         public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
  81.         {
  82.             //Never called from outside the engine
  83.             return this.GetMember(name, bindingAttr, true);
  84.         }
  85.        
  86.         internal MemberInfo[] GetMember(string name, BindingFlags bindingAttr, bool forceInstanceLookup)
  87.         {
  88.             IReflect ir;
  89.             Type t = null;
  90.             BindingFlags attr = bindingAttr;
  91.             if (forceInstanceLookup && this.isSuperType && (bindingAttr & BindingFlags.FlattenHierarchy) == 0)
  92.                 attr |= BindingFlags.Instance;
  93.             object obj = this.contained_object;
  94.             try_again_with_outer_class_instance:
  95.             if (obj is IReflect) {
  96.                 ir = (IReflect)(obj);
  97.                 if (obj is Type && !this.isSuperType)
  98.                     attr &= ~BindingFlags.Instance;
  99.             }
  100.             else
  101.                 ir = t = Globals.TypeRefs.ToReferenceContext(obj.GetType());
  102.             MemberInfo[] members = ir.GetMember(name, attr & ~BindingFlags.DeclaredOnly);
  103.             if (members.Length > 0)
  104.                 return ScriptObject.WrapMembers(members, obj);
  105.             if (obj is Type && !this.isSuperType)
  106.                 members = Typeob.Type.GetMember(name, BindingFlags.Instance | BindingFlags.Public);
  107.             if (members.Length > 0)
  108.                 return ScriptObject.WrapMembers(members, obj);
  109.             if (t != null && t.IsNestedPublic) {
  110.                 //Might happen during call to eval
  111.                 try {
  112.                     new ReflectionPermission(ReflectionPermissionFlag.TypeInformation | ReflectionPermissionFlag.MemberAccess).Assert();
  113.                     FieldInfo outerClassInstance = t.GetField("outer class instance", BindingFlags.NonPublic | BindingFlags.Instance);
  114.                     if (outerClassInstance != null) {
  115.                         obj = outerClassInstance.GetValue(obj);
  116.                         goto try_again_with_outer_class_instance;
  117.                     }
  118.                 }
  119.                 finally {
  120.                     CodeAccessPermission.RevertAssert();
  121.                 }
  122.             }
  123.             if (members.Length > 0)
  124.                 return ScriptObject.WrapMembers(members, obj);
  125.             return new MemberInfo[0];
  126.         }
  127.        
  128.         public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
  129.         {
  130.             //Only called when part of the parent chain of a ClassScope
  131.             return ((IReflect)this.contained_object).GetMembers(bindingAttr);
  132.         }
  133.        
  134.         #if !DEBUG
  135.         [DebuggerStepThroughAttribute()]
  136.         [DebuggerHiddenAttribute()]
  137.         #endif
  138.         internal override object GetMemberValue(string name)
  139.         {
  140.             object result = LateBinding.GetMemberValue2(this.contained_object, name);
  141.             if (!(result is Missing))
  142.                 return result;
  143.             if (this.parent != null)
  144.                 return this.parent.GetMemberValue(name);
  145.             return Missing.Value;
  146.         }
  147.        
  148.         #if !DEBUG
  149.         [DebuggerStepThroughAttribute()]
  150.         [DebuggerHiddenAttribute()]
  151.         #endif
  152.         public object GetMemberValue(string name, int lexlevel)
  153.         {
  154.             if (lexlevel <= 0)
  155.                 return Missing.Value;
  156.             object result = LateBinding.GetMemberValue2(this.contained_object, name);
  157.             if (result != Missing.Value)
  158.                 return result;
  159.             return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel - 1);
  160.         }
  161.        
  162.         #if !DEBUG
  163.         [DebuggerStepThroughAttribute()]
  164.         [DebuggerHiddenAttribute()]
  165.         #endif
  166.         internal override void SetMemberValue(string name, object value)
  167.         {
  168.             if (LateBinding.GetMemberValue2(this.contained_object, name) is Missing)
  169.                 ((ScriptObject)this.parent).SetMemberValue(name, value);
  170.             else
  171.                 LateBinding.SetMemberValue(this.contained_object, name, value);
  172.         }
  173.     }
  174.    
  175. }

Developer Fusion