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

  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.Collections;
  21.     using System.Diagnostics;
  22.    
  23.     /// <internalonly/>
  24.     [System.Runtime.InteropServices.ComVisible(true)]
  25.     public abstract class ActivationObject : ScriptObject, IActivationObject
  26.     {
  27.         internal bool isKnownAtCompileTime;
  28.         internal bool fast;
  29.         internal SimpleHashtable name_table;
  30.         protected ArrayList field_table;
  31.        
  32.         internal ActivationObject(ScriptObject parent) : base(parent)
  33.         {
  34.             this.name_table = new SimpleHashtable(32);
  35.             this.field_table = new ArrayList();
  36.         }
  37.        
  38.         //This method is used to add declared variables/fields to scopes at compile time.
  39.         //It does not add a field if there already is a field with such a name.
  40.        
  41.         internal virtual JSVariableField AddFieldOrUseExistingField(string name, object value, FieldAttributes attributeFlags)
  42.         {
  43.             FieldInfo field = (FieldInfo)(this.name_table[name]);
  44.             if (field is JSVariableField) {
  45.                 if (!(value is Missing))
  46.                     //Do not clobber the existing value unless there is an explicit initializer
  47.                     //This matters when declaring a variable in an eval string (and the calling scope already has such a variable).
  48.                     ((JSVariableField)field).value = value;
  49.                 return (JSVariableField)field;
  50.             }
  51.             if (value is Missing)
  52.                 value = null;
  53.             return this.AddNewField(name, value, attributeFlags);
  54.         }
  55.        
  56.         //Adds a list of classes to result. Superclasses always follow derived classes.
  57.        
  58.         internal void AddClassesExcluding(ClassScope excludedClass, string name, ArrayList result)
  59.         {
  60.             ArrayList eligibleClasses = new ArrayList();
  61.             foreach (MemberInfo member in this.GetMembers(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) {
  62.                 if (member is JSVariableField && ((JSVariableField)member).IsLiteral) {
  63.                     object val = ((JSVariableField)member).value;
  64.                     if (val is ClassScope) {
  65.                         ClassScope csc = (ClassScope)val;
  66.                         if (csc.name != member.Name)
  67.                             continue;
  68.                         if (excludedClass == null || !excludedClass.IsSameOrDerivedFrom(csc))
  69.                             if (csc.GetMember(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).Length > 0)
  70.                                 eligibleClasses.Add(csc);
  71.                     }
  72.                 }
  73.             }
  74.             if (eligibleClasses.Count == 0)
  75.                 return;
  76.             ClassScope[] classes = new ClassScope[eligibleClasses.Count];
  77.             eligibleClasses.CopyTo(classes);
  78.             Array.Sort(classes);
  79.             result.AddRange(classes);
  80.         }
  81.        
  82.         //This method is used when the definition must obliterate an existing definition. For example when adding formal parameters at compile time.
  83.         //It is also used when it is known there is no field with this name, since it does not bother to check.
  84.        
  85.         internal virtual JSVariableField AddNewField(string name, object value, FieldAttributes attributeFlags)
  86.         {
  87.             JSVariableField result = this.CreateField(name, attributeFlags, value);
  88.             this.name_table[name] = result;
  89.             this.field_table.Add(result);
  90.             return result;
  91.         }
  92.        
  93.         //This method requires derived classes to provide the right type of field. (JSLocalField/JSGlobalField/JSMemberField).
  94.        
  95.         protected virtual JSVariableField CreateField(string name, FieldAttributes attributeFlags, object value)
  96.         {
  97.             return new JSGlobalField(this, name, value, attributeFlags | FieldAttributes.Static);
  98.         }
  99.        
  100.         public virtual FieldInfo GetField(string name, int lexLevel)
  101.         {
  102.             throw new JScriptException(JSError.InternalError);
  103.         }
  104.        
  105.         internal virtual string GetName()
  106.         {
  107.             return null;
  108.         }
  109.        
  110.         //IActivationObject methods:
  111.        
  112.         public virtual object GetDefaultThisObject()
  113.         {
  114.             return ((IActivationObject)this.GetParent()).GetDefaultThisObject();
  115.         }
  116.        
  117.         public virtual GlobalScope GetGlobalScope()
  118.         {
  119.             return ((IActivationObject)this.GetParent()).GetGlobalScope();
  120.         }
  121.        
  122.         public virtual FieldInfo GetLocalField(string name)
  123.         {
  124.             return (FieldInfo)this.name_table[name];
  125.         }
  126.        
  127.        
  128.         public override MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
  129.         {
  130.             FieldInfo field = (FieldInfo)(this.name_table[name]);
  131.             if (field != null)
  132.                 return new MemberInfo[] {field};
  133.             if (this.parent != null && (bindingAttr & BindingFlags.DeclaredOnly) == 0)
  134.                 return ScriptObject.WrapMembers(this.parent.GetMember(name, bindingAttr), this.parent);
  135.             return new MemberInfo[0];
  136.         }
  137.        
  138.         public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
  139.         {
  140.             int n = this.field_table.Count;
  141.             MemberInfo[] result = new MemberInfo[n];
  142.             for (int i = 0; i < n; i++)
  143.                 result[i] = (MemberInfo)this.field_table[i];
  144.             return result;
  145.         }
  146.        
  147.         #if !DEBUG
  148.         [DebuggerStepThroughAttribute()]
  149.         [DebuggerHiddenAttribute()]
  150.         #endif
  151.         public object GetMemberValue(string name, int lexlevel)
  152.         {
  153.             if (lexlevel <= 0)
  154.                 return Missing.Value;
  155.             FieldInfo field = (FieldInfo)(this.name_table[name]);
  156.             if (field != null)
  157.                 return field.GetValue(this);
  158.             else if (this.parent != null)
  159.                 return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel - 1);
  160.             else
  161.                 return Missing.Value;
  162.         }
  163.     }
  164. }

Developer Fusion