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

  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 EnumDeclaration : Class
  23.     {
  24.         internal TypeExpression baseType;
  25.        
  26.         internal EnumDeclaration(Context context, IdentifierLiteral id, TypeExpression baseType, Block body, FieldAttributes attributes, CustomAttributeList customAttributes) : base(context, id, new TypeExpression(new ConstantWrapper(Typeob.Enum, null)), new TypeExpression[0], body, attributes, false, false, true, false,
  27.         customAttributes)
  28.         {
  29.             this.baseType = baseType != null ? baseType : new TypeExpression(new ConstantWrapper(Typeob.Int32, null));
  30.             this.needsEngine = false;
  31.             this.attributes &= TypeAttributes.VisibilityMask;
  32.             TypeExpression thisType = new TypeExpression(new ConstantWrapper(this.classob, this.context));
  33.             AST currentValue = new ConstantWrapper(-1, null);
  34.             AST one = new ConstantWrapper(1, null);
  35.             foreach (FieldInfo f in this.fields) {
  36.                 JSVariableField field = (JSVariableField)f;
  37.                 field.attributeFlags = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
  38.                 field.type = thisType;
  39.                 if (field.value == null)
  40.                     field.value = currentValue = new Plus(currentValue.context, currentValue, one);
  41.                 else
  42.                     currentValue = (AST)field.value;
  43.                 field.value = new DeclaredEnumValue(field.value, field.Name, this.classob);
  44.             }
  45.         }
  46.        
  47.         internal override AST PartiallyEvaluate()
  48.         {
  49.             if (!(this.classob.GetParent() is GlobalScope))
  50.                 return this;
  51.             //The class has already been partially evaluated
  52.             this.baseType.PartiallyEvaluate();
  53.             IReflect ir = this.baseType.ToIReflect();
  54.             Type bt = null;
  55.             if (!(ir is Type) || !Convert.IsPrimitiveIntegerType(bt = (Type)ir)) {
  56.                 this.baseType.context.HandleError(JSError.InvalidBaseTypeForEnum);
  57.                 this.baseType = new TypeExpression(new ConstantWrapper(Typeob.Int32, null));
  58.                 bt = Typeob.Int32;
  59.             }
  60.            
  61.             if (this.customAttributes != null)
  62.                 this.customAttributes.PartiallyEvaluate();
  63.            
  64.             if (this.NeedsToBeCheckedForCLSCompliance()) {
  65.                 if (!TypeExpression.TypeIsCLSCompliant(ir))
  66.                     this.baseType.context.HandleError(JSError.NonCLSCompliantType);
  67.                 this.CheckMemberNamesForCLSCompliance();
  68.             }
  69.            
  70.             ScriptObject scope = this.enclosingScope;
  71.             while (!(scope is GlobalScope) && !(scope is PackageScope))
  72.                 scope = scope.GetParent();
  73.             this.classob.SetParent(new WithObject(scope, Typeob.Enum, true));
  74.            
  75.             Globals.ScopeStack.Push(this.classob);
  76.             try {
  77.                 foreach (FieldInfo f in this.fields) {
  78.                     JSMemberField field = (JSMemberField)f;
  79.                     ((DeclaredEnumValue)field.value).CoerceToBaseType(bt, field.originalContext);
  80.                 }
  81.             }
  82.             finally {
  83.                 Globals.ScopeStack.Pop();
  84.             }
  85.             return this;
  86.         }
  87.        
  88.         internal override Type GetTypeBuilderOrEnumBuilder()
  89.         {
  90.             if (this.classob.classwriter != null)
  91.                 return this.classob.classwriter;
  92.             this.PartiallyEvaluate();
  93.             ClassScope classScope = this.enclosingScope as ClassScope;
  94.             if (classScope != null) {
  95.                 TypeBuilder result = ((TypeBuilder)classScope.classwriter).DefineNestedType(this.name, this.attributes | TypeAttributes.Sealed, Typeob.Enum, null);
  96.                 this.classob.classwriter = result;
  97.                 Type underlyingType = this.baseType.ToType();
  98.                 FieldBuilder fb = result.DefineField("value__", underlyingType, FieldAttributes.Private | FieldAttributes.SpecialName);
  99.                 if (this.customAttributes != null) {
  100.                     CustomAttributeBuilder[] custAtt = this.customAttributes.GetCustomAttributeBuilders(false);
  101.                     for (int j = 0; j < custAtt.Length; j++)
  102.                         result.SetCustomAttribute(custAtt[j]);
  103.                 }
  104.                 foreach (FieldInfo field in this.fields) {
  105.                     ((JSMemberField)field).metaData = fb = result.DefineField(field.Name, result, FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal);
  106.                     fb.SetConstant(((EnumWrapper)field.GetValue(null)).ToNumericValue());
  107.                 }
  108.                 return result;
  109.             }
  110.             else {
  111.                 EnumBuilder result = compilerGlobals.module.DefineEnum(this.name, this.attributes, this.baseType.ToType());
  112.                 this.classob.classwriter = result;
  113.                 if (this.customAttributes != null) {
  114.                     CustomAttributeBuilder[] custAtt = this.customAttributes.GetCustomAttributeBuilders(false);
  115.                     for (int j = 0; j < custAtt.Length; j++)
  116.                         result.SetCustomAttribute(custAtt[j]);
  117.                 }
  118.                 foreach (FieldInfo field in this.fields)
  119.                     ((JSMemberField)field).metaData = result.DefineLiteral(field.Name, ((EnumWrapper)field.GetValue(null)).ToNumericValue());
  120.                 return result;
  121.             }
  122.         }
  123.     }
  124. }

Developer Fusion