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

  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.Reflection.Emit;
  21.    
  22.     internal sealed class ThisLiteral : AST
  23.     {
  24.         internal bool isSuper;
  25.         private MethodInfo method;
  26.        
  27.         internal ThisLiteral(Context context, bool isSuper) : base(context)
  28.         {
  29.             this.isSuper = isSuper;
  30.             this.method = null;
  31.         }
  32.        
  33.         internal override void CheckIfOKToUseInSuperConstructorCall()
  34.         {
  35.             this.context.HandleError(JSError.NotAllowedInSuperConstructorCall);
  36.         }
  37.        
  38.         internal override object Evaluate()
  39.         {
  40.             ScriptObject top = Globals.ScopeStack.Peek();
  41.             while (top is WithObject || top is BlockScope)
  42.                 top = top.GetParent();
  43.             if (top is StackFrame)
  44.                 return ((StackFrame)top).thisObject;
  45.             else
  46.                 //Code is either local to function/method/constructor/initializer (StackFrame) or global (GlobalScope)
  47.                 return ((GlobalScope)top).thisObject;
  48.         }
  49.        
  50.         internal override IReflect InferType(JSField inference_target)
  51.         {
  52.             Debug.Assert(Globals.TypeRefs.InReferenceContext(this.method));
  53.             if (this.method != null) {
  54.                 ParameterInfo[] pars = this.method.GetParameters();
  55.                 if (pars == null || pars.Length == 0)
  56.                     return this.method.ReturnType;
  57.                 else
  58.                     return pars[0].ParameterType;
  59.             }
  60.             ScriptObject top = Globals.ScopeStack.Peek();
  61.             while (top is WithObject)
  62.                 top = top.GetParent();
  63.             if (top is GlobalScope)
  64.                 return top;
  65.             else if (top is FunctionScope && ((FunctionScope)top).isMethod) {
  66.                 ClassScope csc = (ClassScope)((FunctionScope)top).owner.enclosing_scope;
  67.                 if (this.isSuper)
  68.                     return csc.GetSuperType();
  69.                 else
  70.                     return csc;
  71.             }
  72.             return Typeob.Object;
  73.         }
  74.        
  75.         internal override AST PartiallyEvaluate()
  76.         {
  77.             ScriptObject top = Globals.ScopeStack.Peek();
  78.             while (top is WithObject)
  79.                 top = top.GetParent();
  80.             bool isStatic = false;
  81.             if (top is FunctionScope)
  82.                 isStatic = ((FunctionScope)top).isStatic && ((FunctionScope)top).isMethod;
  83.             else if (top is StackFrame)
  84.                 isStatic = ((StackFrame)top).thisObject is Type;
  85.             if (isStatic) {
  86.                 this.context.HandleError(JSError.NotAccessible);
  87.                 return (new Lookup("this", this.context)).PartiallyEvaluate();
  88.             }
  89.             return this;
  90.         }
  91.        
  92.         internal override AST PartiallyEvaluateAsReference()
  93.         {
  94.             this.context.HandleError(JSError.CantAssignThis);
  95.             return (new Lookup("this", this.context)).PartiallyEvaluateAsReference();
  96.         }
  97.        
  98.         internal void ResolveAssignmentToDefaultIndexedProperty(ASTList args, IReflect[] argIRs, AST rhvalue)
  99.         {
  100.             IReflect ir = this.InferType(null);
  101.             Type t = ir is Type ? (Type)ir : null;
  102.             if (ir is ClassScope)
  103.                 t = ((ClassScope)ir).GetBakedSuperType();
  104.             MemberInfo[] defaultMembers = JSBinder.GetDefaultMembers(t);
  105.             if (defaultMembers != null && defaultMembers.Length > 0) {
  106.                 try {
  107.                     PropertyInfo prop = JSBinder.SelectProperty(defaultMembers, argIRs);
  108.                     //Returns property getters as well
  109.                     if (prop != null) {
  110.                         this.method = JSProperty.GetSetMethod(prop, true);
  111.                         if (this.method == null)
  112.                             this.context.HandleError(JSError.AssignmentToReadOnly, true);
  113.                         if (!Binding.CheckParameters(prop.GetIndexParameters(), argIRs, args, this.context, 0, false, true))
  114.                             this.method = null;
  115.                         return;
  116.                     }
  117.                 }
  118.                 catch (AmbiguousMatchException) {
  119.                     this.context.HandleError(JSError.AmbiguousMatch);
  120.                     return;
  121.                 }
  122.             }
  123.             string tname = ir is ClassScope ? ((ClassScope)ir).GetName() : ((Type)ir).Name;
  124.             this.context.HandleError(JSError.NotIndexable, tname);
  125.         }
  126.        
  127.         internal override void ResolveCall(ASTList args, IReflect[] argIRs, bool constructor, bool brackets)
  128.         {
  129.             if (constructor || !brackets) {
  130.                 if (this.isSuper)
  131.                     this.context.HandleError(JSError.IllegalUseOfSuper);
  132.                 else
  133.                     this.context.HandleError(JSError.IllegalUseOfThis);
  134.                 return;
  135.             }
  136.             IReflect ir = this.InferType(null);
  137.             Type t = ir is Type ? (Type)ir : null;
  138.             if (ir is ClassScope)
  139.                 t = ((ClassScope)ir).GetBakedSuperType();
  140.             MemberInfo[] defaultMembers = JSBinder.GetDefaultMembers(t);
  141.             if (defaultMembers != null && defaultMembers.Length > 0) {
  142.                 try {
  143.                     this.method = JSBinder.SelectMethod(defaultMembers, argIRs);
  144.                     //Returns property getters as well
  145.                     if (this.method != null) {
  146.                         if (!Binding.CheckParameters(this.method.GetParameters(), argIRs, args, this.context, 0, false, true))
  147.                             this.method = null;
  148.                         return;
  149.                     }
  150.                 }
  151.                 catch (AmbiguousMatchException) {
  152.                     this.context.HandleError(JSError.AmbiguousMatch);
  153.                     return;
  154.                 }
  155.             }
  156.             string tname = ir is ClassScope ? ((ClassScope)ir).GetName() : ((Type)ir).Name;
  157.             this.context.HandleError(JSError.NotIndexable, tname);
  158.         }
  159.        
  160.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  161.         {
  162.             if (rtype == Typeob.Void)
  163.                 return;
  164.             IReflect ir = this.InferType(null);
  165.             if (ir is GlobalScope) {
  166.                 this.EmitILToLoadEngine(il);
  167.                 if (rtype == Typeob.LenientGlobalObject)
  168.                     il.Emit(OpCodes.Call, CompilerGlobals.getLenientGlobalObjectMethod);
  169.                 else {
  170.                     il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod);
  171.                     il.Emit(OpCodes.Castclass, Typeob.IActivationObject);
  172.                     il.Emit(OpCodes.Callvirt, CompilerGlobals.getDefaultThisObjectMethod);
  173.                 }
  174.                 return;
  175.             }
  176.             il.Emit(OpCodes.Ldarg_0);
  177.             Convert.Emit(this, il, Convert.ToType(this.InferType(null)), rtype);
  178.         }
  179.        
  180.         internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets)
  181.         {
  182.             MethodInfo meth = this.method;
  183.             if (meth != null) {
  184.                 Type t = meth.ReflectedType;
  185.                 if (!meth.IsStatic) {
  186.                     this.method = null;
  187.                     this.TranslateToIL(il, t);
  188.                     this.method = meth;
  189.                 }
  190.                 ParameterInfo[] pars = meth.GetParameters();
  191.                 Binding.PlaceArgumentsOnStack(il, pars, argList, 0, 0, Binding.ReflectionMissingCW);
  192.                 if (meth.IsVirtual && !meth.IsFinal && (!t.IsSealed || !t.IsValueType))
  193.                     il.Emit(OpCodes.Callvirt, meth);
  194.                 else
  195.                     il.Emit(OpCodes.Call, meth);
  196.                 Convert.Emit(this, il, meth.ReturnType, rtype);
  197.             }
  198.             else
  199.                 base.TranslateToILCall(il, rtype, argList, construct, brackets);
  200.         }
  201.        
  202.         internal override void TranslateToILPreSet(ILGenerator il, ASTList argList)
  203.         {
  204.             MethodInfo meth = this.method;
  205.             if (meth != null) {
  206.                 Type t = meth.ReflectedType;
  207.                 if (!meth.IsStatic)
  208.                     this.TranslateToIL(il, t);
  209.                 Binding.PlaceArgumentsOnStack(il, meth.GetParameters(), argList, 0, 1, Binding.ReflectionMissingCW);
  210.             }
  211.             else
  212.                 base.TranslateToILPreSet(il, argList);
  213.         }
  214.        
  215.         internal override void TranslateToILSet(ILGenerator il, AST rhvalue)
  216.         {
  217.             MethodInfo meth = this.method;
  218.             if (meth != null) {
  219.                 if (rhvalue != null)
  220.                     rhvalue.TranslateToIL(il, meth.GetParameters()[0].ParameterType);
  221.                 Type t = meth.ReflectedType;
  222.                 if (meth.IsVirtual && !meth.IsFinal && (!t.IsSealed || !t.IsValueType))
  223.                     il.Emit(OpCodes.Callvirt, meth);
  224.                 else
  225.                     il.Emit(OpCodes.Call, meth);
  226.                 if (meth.ReturnType != Typeob.Void)
  227.                     //Should never be the case if the property is well formed, but there is no gaurantee
  228.                     il.Emit(OpCodes.Pop);
  229.             }
  230.             else
  231.                 base.TranslateToILSet(il, rhvalue);
  232.         }
  233.        
  234.         internal override void TranslateToILInitializer(ILGenerator il)
  235.         {
  236.         }
  237.        
  238.     }
  239. }

Developer Fusion