Files
yallie 9fa3874800 Added the contents of the archive.
Moved the original file to the archive subfolder.
2017-11-20 16:11:42 +03:00

144 lines
5.7 KiB
C#

// ==++==
//
//
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
namespace Microsoft.JScript
{
using System;
using System.Reflection;
using System.Collections;
using System.Diagnostics;
public abstract class ActivationObject : ScriptObject, IActivationObject{
internal bool isKnownAtCompileTime;
internal bool fast;
internal SimpleHashtable name_table;
protected ArrayList field_table;
internal ActivationObject(ScriptObject parent)
: base(parent) {
this.name_table = new SimpleHashtable(32);
this.field_table = new ArrayList();
}
//This method is used to add declared variables/fields to scopes at compile time.
//It does not add a field if there already is a field with such a name.
internal virtual JSVariableField AddFieldOrUseExistingField(String name, Object value, FieldAttributes attributeFlags){
FieldInfo field = (FieldInfo)(this.name_table[name]);
if (field is JSVariableField){
if (!(value is Missing))
//Do not clobber the existing value unless there is an explicit initializer
//This matters when declaring a variable in an eval string (and the calling scope already has such a variable).
((JSVariableField)field).value = value;
return (JSVariableField)field;
}
if (value is Missing) value = null;
return this.AddNewField(name, value, attributeFlags);
}
//Adds a list of classes to result. Superclasses always follow derived classes.
internal void AddClassesExcluding(ClassScope excludedClass, String name, ArrayList result){
ArrayList eligibleClasses = new ArrayList();
foreach (MemberInfo member in this.GetMembers(BindingFlags.Static|BindingFlags.Public|BindingFlags.NonPublic)){
if (member is JSVariableField && ((JSVariableField)member).IsLiteral){
Object val = ((JSVariableField)member).value;
if (val is ClassScope){
ClassScope csc = (ClassScope)val;
if (csc.name != member.Name) continue;
if (excludedClass == null || !excludedClass.IsSameOrDerivedFrom(csc))
if (csc.GetMember(name, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.DeclaredOnly).Length > 0)
eligibleClasses.Add(csc);
}
}
}
if (eligibleClasses.Count == 0) return;
ClassScope[] classes = new ClassScope[eligibleClasses.Count]; eligibleClasses.CopyTo(classes);
Array.Sort(classes);
result.AddRange(classes);
}
//This method is used when the definition must obliterate an existing definition. For example when adding formal parameters at compile time.
//It is also used when it is known there is no field with this name, since it does not bother to check.
internal virtual JSVariableField AddNewField(String name, Object value, FieldAttributes attributeFlags){
JSVariableField result = this.CreateField(name, attributeFlags, value);
this.name_table[name] = result;
this.field_table.Add(result);
return result;
}
//This method requires derived classes to provide the right type of field. (JSLocalField/JSGlobalField/JSMemberField).
protected virtual JSVariableField CreateField(String name, FieldAttributes attributeFlags, Object value){
return new JSGlobalField(this, name, value, attributeFlags|FieldAttributes.Static);
}
public virtual FieldInfo GetField(String name, int lexLevel){
throw new JScriptException(JSError.InternalError);
}
internal virtual String GetName(){
return null;
}
//IActivationObject methods:
public virtual Object GetDefaultThisObject(){
return ((IActivationObject)this.GetParent()).GetDefaultThisObject();
}
public virtual GlobalScope GetGlobalScope(){
return ((IActivationObject)this.GetParent()).GetGlobalScope();
}
public virtual FieldInfo GetLocalField(String name){
return (FieldInfo)this.name_table[name];
}
public override MemberInfo[] GetMember(String name, BindingFlags bindingAttr){
FieldInfo field = (FieldInfo)(this.name_table[name]);
if (field != null) return new MemberInfo[]{field};
if (this.parent != null && (bindingAttr&BindingFlags.DeclaredOnly) == 0)
return ScriptObject.WrapMembers(this.parent.GetMember(name, bindingAttr), this.parent);
return new MemberInfo[0];
}
public override MemberInfo[] GetMembers(BindingFlags bindingAttr){
int n = this.field_table.Count;
MemberInfo[] result = new MemberInfo[n];
for (int i = 0; i < n; i++) result[i] = (MemberInfo)this.field_table[i];
return result;
}
#if !DEBUG
[DebuggerStepThroughAttribute]
[DebuggerHiddenAttribute]
#endif
public Object GetMemberValue(String name, int lexlevel){
if (lexlevel <= 0)
return Missing.Value;
FieldInfo field = (FieldInfo)(this.name_table[name]);
if (field != null)
return field.GetValue(this);
else if (this.parent != null)
return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel-1);
else
return Missing.Value;
}
}
}