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

  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 SwitchCase : AST
  23.     {
  24.         private AST case_value;
  25.         private AST statements;
  26.         private Completion completion;
  27.        
  28.         internal SwitchCase(Context context, AST statements) : this(context, null, statements)
  29.         {
  30.         }
  31.        
  32.         internal SwitchCase(Context context, AST case_value, AST statements) : base(context)
  33.         {
  34.             this.case_value = case_value;
  35.             this.statements = statements;
  36.             this.completion = new Completion();
  37.         }
  38.        
  39.         internal override object Evaluate()
  40.         {
  41.             return this.statements.Evaluate();
  42.         }
  43.        
  44.         internal Completion Evaluate(object expression)
  45.         {
  46.             Debug.PreCondition(this.case_value != null);
  47.             if (StrictEquality.JScriptStrictEquals(this.case_value.Evaluate(), expression))
  48.                 return (Completion)this.statements.Evaluate();
  49.             else
  50.                 return null;
  51.         }
  52.        
  53.         internal bool IsDefault()
  54.         {
  55.             return case_value == null;
  56.         }
  57.        
  58.         internal override AST PartiallyEvaluate()
  59.         {
  60.             if (this.case_value != null)
  61.                 this.case_value = this.case_value.PartiallyEvaluate();
  62.             this.statements = this.statements.PartiallyEvaluate();
  63.             return this;
  64.         }
  65.        
  66.         internal void TranslateToConditionalBranch(ILGenerator il, Type etype, bool branchIfTrue, Label label, bool shortForm)
  67.         {
  68.             Debug.PreCondition(this.case_value != null);
  69.             Type t1 = etype;
  70.             Type t2 = Convert.ToType(this.case_value.InferType(null));
  71.             if (t1 != t2 && t1.IsPrimitive && t2.IsPrimitive) {
  72.                 if (t1 == Typeob.Single && t2 == Typeob.Double)
  73.                     t2 = Typeob.Single;
  74.                 else if (Convert.IsPromotableTo(t2, t1))
  75.                     t2 = t1;
  76.                 else if (Convert.IsPromotableTo(t1, t2))
  77.                     t1 = t2;
  78.             }
  79.             bool nonPrimitive = true;
  80.             if (t1 == t2 && t1 != Typeob.Object) {
  81.                 Convert.Emit(this, il, etype, t1);
  82.                 if (!t1.IsPrimitive && t1.IsValueType)
  83.                     il.Emit(OpCodes.Box, t1);
  84.                 this.case_value.context.EmitLineInfo(il);
  85.                 this.case_value.TranslateToIL(il, t1);
  86.                 if (t1 == Typeob.String)
  87.                     il.Emit(OpCodes.Call, CompilerGlobals.stringEqualsMethod);
  88.                 else if (!t1.IsPrimitive) {
  89.                     if (t1.IsValueType)
  90.                         il.Emit(OpCodes.Box, t1);
  91.                     il.Emit(OpCodes.Callvirt, CompilerGlobals.equalsMethod);
  92.                 }
  93.                 else
  94.                     nonPrimitive = false;
  95.             }
  96.             else {
  97.                 Convert.Emit(this, il, etype, Typeob.Object);
  98.                 this.case_value.context.EmitLineInfo(il);
  99.                 this.case_value.TranslateToIL(il, Typeob.Object);
  100.                 il.Emit(OpCodes.Call, CompilerGlobals.jScriptStrictEqualsMethod);
  101.             }
  102.             if (branchIfTrue) {
  103.                 if (nonPrimitive)
  104.                     il.Emit(shortForm ? OpCodes.Brtrue_S : OpCodes.Brtrue, label);
  105.                 else
  106.                     il.Emit(shortForm ? OpCodes.Beq_S : OpCodes.Beq, label);
  107.             }
  108.             else {
  109.                 if (nonPrimitive)
  110.                     il.Emit(shortForm ? OpCodes.Brfalse_S : OpCodes.Brfalse, label);
  111.                 else
  112.                     il.Emit(shortForm ? OpCodes.Bne_Un_S : OpCodes.Bne_Un, label);
  113.             }
  114.         }
  115.        
  116.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  117.         {
  118.             //This assumes that rtype == Void.class
  119.             this.statements.TranslateToIL(il, Typeob.Void);
  120.         }
  121.        
  122.         internal override void TranslateToILInitializer(ILGenerator il)
  123.         {
  124.             if (this.case_value != null)
  125.                 this.case_value.TranslateToILInitializer(il);
  126.             this.statements.TranslateToILInitializer(il);
  127.         }
  128.     }
  129. }

Developer Fusion