mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
144 lines
5.7 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|