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.
150 lines
5.6 KiB
C#
150 lines
5.6 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.Diagnostics;
|
|
|
|
internal sealed class WithObject : ScriptObject, IActivationObject{
|
|
internal Object contained_object;
|
|
internal bool isKnownAtCompileTime;
|
|
private bool isSuperType;
|
|
|
|
internal WithObject(ScriptObject parent, Object contained_object)
|
|
: this(parent, contained_object, false) {
|
|
}
|
|
|
|
internal WithObject(ScriptObject parent, Object contained_object, bool isSuperType)
|
|
: base(parent) {
|
|
this.contained_object = contained_object;
|
|
this.isKnownAtCompileTime = contained_object is Type ||
|
|
(contained_object is ClassScope && ((ClassScope)contained_object).noExpando) ||
|
|
(contained_object is JSObject && ((JSObject)contained_object).noExpando);
|
|
this.isSuperType = isSuperType;
|
|
}
|
|
|
|
public Object GetDefaultThisObject(){
|
|
return this.contained_object;
|
|
}
|
|
|
|
public FieldInfo GetField(String name, int lexLevel){
|
|
if (lexLevel <= 0)
|
|
return null;
|
|
IReflect ir;
|
|
if (this.contained_object is IReflect)
|
|
ir = (IReflect)(this.contained_object);
|
|
else
|
|
ir = (IReflect)(this.contained_object.GetType());
|
|
FieldInfo field = ir.GetField(name, BindingFlags.Instance|BindingFlags.Static|BindingFlags.FlattenHierarchy|BindingFlags.Public);
|
|
if (field != null)
|
|
return new JSWrappedField(field, this.contained_object);
|
|
PropertyInfo prop = ir.GetProperty(name, BindingFlags.Instance|BindingFlags.Static|BindingFlags.Public);
|
|
if (prop != null)
|
|
return new JSPropertyField(prop, this.contained_object);
|
|
if (this.parent != null && lexLevel > 1){
|
|
field = ((IActivationObject)this.parent).GetField(name, lexLevel-1);
|
|
if (field != null)
|
|
return new JSWrappedField(field, this.parent);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public GlobalScope GetGlobalScope(){
|
|
return ((IActivationObject)this.GetParent()).GetGlobalScope();
|
|
}
|
|
|
|
FieldInfo IActivationObject.GetLocalField(String name){
|
|
Debug.Assert(false);
|
|
return null;
|
|
}
|
|
|
|
public override MemberInfo[] GetMember(String name, BindingFlags bindingAttr){ //Never called from outside the engine
|
|
IReflect ir;
|
|
Type t = null;
|
|
BindingFlags attr = bindingAttr;
|
|
if (this.isSuperType && (bindingAttr & BindingFlags.FlattenHierarchy) == 0) attr |= BindingFlags.Instance;
|
|
Object obj = this.contained_object;
|
|
try_again_with_outer_class_instance:
|
|
if (obj is IReflect){
|
|
ir = (IReflect)(obj);
|
|
if (obj is Type && !this.isSuperType)
|
|
attr &= ~BindingFlags.Instance;
|
|
}else
|
|
ir = t = obj.GetType();
|
|
MemberInfo[] members = ir.GetMember(name, attr&~BindingFlags.DeclaredOnly);
|
|
if (members.Length > 0)
|
|
return ScriptObject.WrapMembers(members, obj);
|
|
if (obj is Type && !this.isSuperType)
|
|
members = Typeob.Type.GetMember(name, BindingFlags.Instance|BindingFlags.Public);
|
|
if (members.Length > 0)
|
|
return ScriptObject.WrapMembers(members, obj);
|
|
if (t != null && t.IsNestedPublic){ //Might happen during call to eval
|
|
FieldInfo outerClassInstance = t.GetField("outer class instance", BindingFlags.NonPublic|BindingFlags.Instance);
|
|
if (outerClassInstance != null){
|
|
obj = outerClassInstance.GetValue(obj);
|
|
goto try_again_with_outer_class_instance;
|
|
}
|
|
}
|
|
if (members.Length > 0)
|
|
return ScriptObject.WrapMembers(members, obj);
|
|
return new MemberInfo[0];
|
|
}
|
|
|
|
public override MemberInfo[] GetMembers(BindingFlags bindingAttr){ //Only called when part of the parent chain of a ClassScope
|
|
return ((IReflect)this.contained_object).GetMembers(bindingAttr);
|
|
}
|
|
|
|
#if !DEBUG
|
|
[DebuggerStepThroughAttribute]
|
|
[DebuggerHiddenAttribute]
|
|
#endif
|
|
internal override Object GetMemberValue(String name){
|
|
Object result = LateBinding.GetMemberValue2(this.contained_object, name);
|
|
if (!(result is Missing))
|
|
return result;
|
|
if (this.parent != null)
|
|
return this.parent.GetMemberValue(name);
|
|
return Missing.Value;
|
|
}
|
|
|
|
#if !DEBUG
|
|
[DebuggerStepThroughAttribute]
|
|
[DebuggerHiddenAttribute]
|
|
#endif
|
|
public Object GetMemberValue(String name, int lexlevel){
|
|
if (lexlevel <= 0)
|
|
return Missing.Value;
|
|
Object result = LateBinding.GetMemberValue2(this.contained_object, name);
|
|
if (result != Missing.Value)
|
|
return result;
|
|
return ((IActivationObject)this.parent).GetMemberValue(name, lexlevel-1);
|
|
}
|
|
|
|
#if !DEBUG
|
|
[DebuggerStepThroughAttribute]
|
|
[DebuggerHiddenAttribute]
|
|
#endif
|
|
internal override void SetMemberValue(String name, Object value){
|
|
if (LateBinding.GetMemberValue2(this.contained_object, name) is Missing)
|
|
((ScriptObject)this.parent).SetMemberValue(name, value);
|
|
else
|
|
LateBinding.SetMemberValue(this.contained_object, name, value);
|
|
}
|
|
}
|
|
|
|
}
|