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

  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 Microsoft.JScript.Vsa;
  19.     using System;
  20.     using System.Collections;
  21.     using System.Globalization;
  22.     using System.Reflection;
  23.     using System.Reflection.Emit;
  24.     using System.Text;
  25.    
  26.     internal class Class : AST
  27.     {
  28.         internal string name;
  29.         private TypeExpression superTypeExpression;
  30.         private TypeExpression[] interfaces;
  31.         internal Block body;
  32.         internal ScriptObject enclosingScope;
  33.         internal TypeAttributes attributes;
  34.         private bool hasAlreadyBeenAskedAboutExpando;
  35.         internal bool isAbstract;
  36.         private bool isAlreadyPartiallyEvaluated;
  37.         private bool isCooked;
  38.         private Type cookedType;
  39.         private bool isExpando;
  40.         internal bool isInterface;
  41.         internal bool isStatic;
  42.         protected bool needsEngine;
  43.         internal AttributeTargets validOn;
  44.         internal bool allowMultiple;
  45.         protected ClassScope classob;
  46.         private FunctionObject implicitDefaultConstructor;
  47.         private JSVariableField ownField;
  48.         protected JSMemberField[] fields;
  49.         private Class superClass;
  50.         private IReflect superIR;
  51.         private object[] superMembers;
  52.         private SimpleHashtable firstIndex;
  53.         private MethodInfo fieldInitializer;
  54.         internal CustomAttributeList customAttributes;
  55.         internal CLSComplianceSpec clsCompliance;
  56.         // expando related fields
  57.         private bool generateCodeForExpando;
  58.         // true if this class is the first expando class in a hierarchy chain
  59.         private PropertyBuilder expandoItemProp;
  60.         private MethodBuilder getHashTableMethod;
  61.         private MethodBuilder getItem;
  62.         private MethodBuilder setItem;
  63.         internal MethodBuilder deleteOpMethod;
  64.         private static int badTypeNameCount = 0;
  65.         // If the type name is invalid, we generate one using "bad type name " + this index.
  66.         internal Class(Context context, AST id, TypeExpression superTypeExpression, TypeExpression[] interfaces, Block body, FieldAttributes attributes, bool isAbstract, bool isFinal, bool isStatic, bool isInterface,
  67.         CustomAttributeList customAttributes) : base(context)
  68.         {
  69.             this.name = id.ToString();
  70.             this.superTypeExpression = superTypeExpression;
  71.             this.interfaces = interfaces;
  72.             this.body = body;
  73.             this.enclosingScope = (ScriptObject)Globals.ScopeStack.Peek(1);
  74.             this.attributes = TypeAttributes.Class | TypeAttributes.Serializable;
  75.             this.SetAccessibility(attributes);
  76.             if (isAbstract)
  77.                 this.attributes |= TypeAttributes.Abstract;
  78.             this.isAbstract = isAbstract || isInterface;
  79.             this.isAlreadyPartiallyEvaluated = false;
  80.             if (isFinal)
  81.                 this.attributes |= TypeAttributes.Sealed;
  82.             if (isInterface)
  83.                 this.attributes |= TypeAttributes.Interface | TypeAttributes.Abstract;
  84.             this.isCooked = false;
  85.             this.cookedType = null;
  86.             this.isExpando = false;
  87.             this.isInterface = isInterface;
  88.             this.isStatic = isStatic;
  89.             this.needsEngine = !isInterface;
  90.             this.validOn = (AttributeTargets)0;
  91.             this.allowMultiple = true;
  92.             this.classob = (ClassScope)Globals.ScopeStack.Peek();
  93.             this.classob.name = this.name;
  94.             this.classob.owner = this;
  95.             this.implicitDefaultConstructor = null;
  96.             if (!isInterface && !(this is EnumDeclaration))
  97.                 this.SetupConstructors();
  98.             this.EnterNameIntoEnclosingScopeAndGetOwnField(id, isStatic);
  99.             this.fields = this.classob.GetMemberFields();
  100.             this.superClass = null;
  101.             this.superIR = null;
  102.             this.superMembers = null;
  103.             this.firstIndex = null;
  104.             this.fieldInitializer = null;
  105.             this.customAttributes = customAttributes;
  106.             this.clsCompliance = CLSComplianceSpec.NotAttributed;
  107.             this.generateCodeForExpando = false;
  108.             this.expandoItemProp = null;
  109.             this.getHashTableMethod = null;
  110.             this.getItem = null;
  111.             this.setItem = null;
  112.         }
  113.        
  114.         private void AddImplicitInterfaces(IReflect iface, IReflect[] explicitInterfaces, ArrayList implicitInterfaces)
  115.         {
  116.             Type ifaceT = iface as Type;
  117.             if (ifaceT != null) {
  118.                 Type[] implInterfaces = ifaceT.GetInterfaces();
  119.                 foreach (Type implIface in implInterfaces) {
  120.                     if (Array.IndexOf(explicitInterfaces, implIface, 0) >= 0)
  121.                         return;
  122.                     if (implicitInterfaces.IndexOf(implIface, 0) >= 0)
  123.                         return;
  124.                     implicitInterfaces.Add(implIface);
  125.                 }
  126.                 return;
  127.             }
  128.             foreach (TypeExpression ifaceExpr in ((ClassScope)iface).owner.interfaces) {
  129.                 IReflect implIface = ifaceExpr.ToIReflect();
  130.                 if (Array.IndexOf(explicitInterfaces, implIface, 0) >= 0)
  131.                     return;
  132.                 if (implicitInterfaces.IndexOf(implIface, 0) >= 0)
  133.                     return;
  134.                 implicitInterfaces.Add(implIface);
  135.             }
  136.             return;
  137.         }
  138.        
  139.         private void AllocateImplicitDefaultConstructor()
  140.         {
  141.             this.implicitDefaultConstructor = new FunctionObject(".ctor", new ParameterDeclaration[0], null, new Block(this.context), new FunctionScope(this.classob, true), this.classob, this.context, MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Public, null, true
  142.             );
  143.             this.implicitDefaultConstructor.isImplicitCtor = true;
  144.             this.implicitDefaultConstructor.isConstructor = true;
  145.             this.implicitDefaultConstructor.proto = this.classob;
  146.         }
  147.        
  148.         private bool CanSee(MemberInfo member)
  149.         {
  150.             switch (member.MemberType) {
  151.                 case MemberTypes.Method:
  152.                    
  153.                     {
  154.                         MethodAttributes visibility = ((MethodBase)member).Attributes & MethodAttributes.MemberAccessMask;
  155.                         if (visibility == MethodAttributes.Private || visibility == MethodAttributes.PrivateScope || visibility == MethodAttributes.FamANDAssem)
  156.                             return false;
  157.                         if (visibility == MethodAttributes.Assembly)
  158.                             return IsInTheSamePackage(member);
  159.                         return true;
  160.                     }
  161.                     break;
  162.                 case MemberTypes.Field:
  163.                    
  164.                     {
  165.                         FieldAttributes visibility = ((FieldInfo)member).Attributes & FieldAttributes.FieldAccessMask;
  166.                         if (visibility == FieldAttributes.Private || visibility == FieldAttributes.PrivateScope || visibility == FieldAttributes.FamANDAssem)
  167.                             return false;
  168.                         if (visibility == FieldAttributes.Assembly)
  169.                             return IsInTheSamePackage(member);
  170.                         return true;
  171.                     }
  172.                     break;
  173.                 case MemberTypes.Property:
  174.                    
  175.                     {
  176.                         MethodBase propMethod = JSProperty.GetGetMethod((PropertyInfo)member, true);
  177.                         if (propMethod == null)
  178.                             propMethod = JSProperty.GetSetMethod((PropertyInfo)member, true);
  179.                         if (propMethod == null)
  180.                             return false;
  181.                         else {
  182.                             MethodAttributes visibility = propMethod.Attributes & MethodAttributes.MemberAccessMask;
  183.                             if (visibility == MethodAttributes.Private || visibility == MethodAttributes.PrivateScope || visibility == MethodAttributes.FamANDAssem)
  184.                                 return false;
  185.                             if (visibility == MethodAttributes.Assembly)
  186.                                 return IsInTheSamePackage(member);
  187.                         }
  188.                         return true;
  189.                     }
  190.                     break;
  191.                 case MemberTypes.Event:
  192.                    
  193.                     {
  194.                         MethodBase addMethod = ((EventInfo)member).GetAddMethod();
  195.                         if (addMethod == null)
  196.                             return false;
  197.                         else {
  198.                             MethodAttributes visibility = addMethod.Attributes & MethodAttributes.MemberAccessMask;
  199.                             if (visibility == MethodAttributes.Private || visibility == MethodAttributes.PrivateScope || visibility == MethodAttributes.FamANDAssem)
  200.                                 return false;
  201.                             if (visibility == MethodAttributes.Assembly)
  202.                                 return IsInTheSamePackage(member);
  203.                         }
  204.                         return true;
  205.                     }
  206.                     break;
  207.                 case MemberTypes.TypeInfo:
  208.                 case MemberTypes.NestedType:
  209.                    
  210.                     {
  211.                         TypeAttributes visibility = ((Type)member).Attributes & TypeAttributes.VisibilityMask;
  212.                         if (visibility == TypeAttributes.NestedPrivate || visibility == TypeAttributes.NestedFamANDAssem)
  213.                             return false;
  214.                         if (visibility == TypeAttributes.NestedAssembly)
  215.                             return IsInTheSamePackage(member);
  216.                         return true;
  217.                     }
  218.                     break;
  219.             }
  220.             return true;
  221.         }
  222.        
  223.         private void CheckFieldDeclarationConsistency(JSMemberField field)
  224.         {
  225.             object index = this.firstIndex[field.Name];
  226.             if (index == null)
  227.                 return;
  228.             //There is no super class member with the same name as the field
  229.             for (int i = (int)indexint n = this.superMembers.Length; i < n; i++) {
  230.                 object supMem = this.superMembers[i];
  231.                 if (!(supMem is MemberInfo))
  232.                     return;
  233.                 MemberInfo member = (MemberInfo)supMem;
  234.                 if (!member.Name.Equals(field.Name))
  235.                     return;
  236.                 if (this.CanSee(member)) {
  237.                     string supMemberName = this.GetFullNameFor(member);
  238.                     field.originalContext.HandleError(JSError.HidesParentMember, supMemberName, this.IsInTheSameCompilationUnit(member));
  239.                     return;
  240.                 }
  241.             }
  242.         }
  243.        
  244.         private void CheckIfOKToGenerateCodeForExpando(bool superClassIsExpando)
  245.         {
  246.             if (superClassIsExpando) {
  247.                 this.context.HandleError(JSError.BaseClassIsExpandoAlready);
  248.                 this.generateCodeForExpando = false;
  249.                 return;
  250.             }
  251.            
  252.             // make sure the current class does not define an Item property
  253.             if (this.classob.GetMember("Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly).Length > 0) {
  254.                 this.context.HandleError(JSError.ItemNotAllowedOnExpandoClass);
  255.                 this.generateCodeForExpando = false;
  256.                 return;
  257.             }
  258.             if (this.classob.GetMember("get_Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly).Length > 0 || this.classob.GetMember("set_Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly).Length > 0) {
  259.                 this.context.HandleError(JSError.MethodNotAllowedOnExpandoClass);
  260.                 this.generateCodeForExpando = false;
  261.                 return;
  262.             }
  263.            
  264.             // make sure the current class does not implements IEnumerable
  265.             if (this.ImplementsInterface(Typeob.IEnumerable)) {
  266.                 this.context.HandleError(JSError.ExpandoClassShouldNotImpleEnumerable);
  267.                 this.generateCodeForExpando = false;
  268.                 return;
  269.             }
  270.            
  271.             // make sure up in the hierarchy chain no property named 'Item' is defined
  272.             if (this.superIR.GetMember("Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Length > 0 || this.superIR.GetMember("get_Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Length > 0 || this.superIR.GetMember("set_Item", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Length > 0) {
  273.                 this.context.HandleError(JSError.MethodClashOnExpandoSuperClass);
  274.                 this.generateCodeForExpando = false;
  275.                 return;
  276.             }
  277.            
  278.             // add an expando property to the current class for Binding to find
  279.             JSProperty itemProp = this.classob.itemProp = new JSProperty("Item");
  280.             itemProp.getter = new JSExpandoIndexerMethod(this.classob, true);
  281.             itemProp.setter = new JSExpandoIndexerMethod(this.classob, false);
  282.             this.classob.AddNewField("Item", itemProp, FieldAttributes.Literal);
  283.         }
  284.        
  285.         private string GetFullName()
  286.         {
  287.             string scopeName = ((ActivationObject)this.enclosingScope).GetName();
  288.             if (scopeName == null) {
  289.                 VsaEngine engine = this.context.document.engine;
  290.                 if (engine != null && engine.genStartupClass)
  291.                     scopeName = engine.RootNamespace;
  292.             }
  293.             if (scopeName != null)
  294.                 return scopeName + "." + this.name;
  295.             else
  296.                 return this.name;
  297.         }
  298.        
  299.         protected void CheckMemberNamesForCLSCompliance()
  300.         {
  301.             // Check top-level class name for CLS compliance.
  302.             if (!(this.enclosingScope is ClassScope))
  303.                 this.Engine.CheckTypeNameForCLSCompliance(this.name, this.GetFullName(), this.context);
  304.             // Check is all member names are CLS compliant
  305.             Hashtable caseInsensitiveNameTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
  306.             for (int i = 0int n = this.fields.Length; i < n; i++) {
  307.                 JSMemberField field = this.fields[i];
  308.                 if (field.IsPrivate)
  309.                     continue;
  310.                 if (!VsaEngine.CheckIdentifierForCLSCompliance(field.Name))
  311.                     field.originalContext.HandleError(JSError.NonCLSCompliantMember);
  312.                 else {
  313.                     if ((JSMemberField)caseInsensitiveNameTable[field.Name] == null)
  314.                         caseInsensitiveNameTable.Add(field.Name, field);
  315.                     else
  316.                         field.originalContext.HandleError(JSError.NonCLSCompliantMember);
  317.                 }
  318.             }
  319.         }
  320.        
  321.         private void CheckIfValidExtensionOfSuperType()
  322.         {
  323.             this.GetIRForSuperType();
  324.             ClassScope csc = this.superIR as ClassScope;
  325.             if (csc != null) {
  326.                 if (this.IsStatic) {
  327.                     if (!csc.owner.IsStatic) {
  328.                         this.superTypeExpression.context.HandleError(JSError.NestedInstanceTypeCannotBeExtendedByStatic);
  329.                         this.superIR = Typeob.Object;
  330.                         this.superTypeExpression = null;
  331.                     }
  332.                 }
  333.                 else {
  334.                     if (!csc.owner.IsStatic && this.enclosingScope != csc.owner.enclosingScope) {
  335.                         this.superTypeExpression.context.HandleError(JSError.NestedInstanceTypeCannotBeExtendedByStatic);
  336.                         this.superIR = Typeob.Object;
  337.                         this.superTypeExpression = null;
  338.                     }
  339.                 }
  340.             }
  341.             this.GetSuperTypeMembers();
  342.             this.GetStartIndexForEachName();
  343.            
  344.             bool checkCLSCompliance = this.NeedsToBeCheckedForCLSCompliance();
  345.             if (checkCLSCompliance)
  346.                 this.CheckMemberNamesForCLSCompliance();
  347.            
  348.             //First check only the methods the implement interfaces
  349.             for (int i = 0int n = this.fields.Length; i < n; i++) {
  350.                 JSMemberField field = this.fields[i];
  351.                 if (field.IsLiteral) {
  352.                     object value = field.value;
  353.                     if (value is FunctionObject) {
  354.                         JSMemberField startMethod = field;
  355.                         while (true) {
  356.                             FunctionObject func = (FunctionObject)value;
  357.                             if (func.implementedIface == null)
  358.                                 break;
  359.                             this.CheckMethodDeclarationConsistency(func);
  360.                             if (func.implementedIfaceMethod == null)
  361.                                 func.funcContext.HandleError(JSError.NoMethodInBaseToOverride);
  362.                             if (field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly)
  363.                                 func.CheckCLSCompliance(checkCLSCompliance);
  364.                             field = field.nextOverload;
  365.                             if (field == null)
  366.                                 break;
  367.                             value = field.value;
  368.                         }
  369.                         continue;
  370.                     }
  371.                     else if (value is JSProperty) {
  372.                         continue;
  373.                     }
  374.                 }
  375.             }
  376.             for (int i = 0int n = this.fields.Length; i < n; i++) {
  377.                 JSMemberField field = this.fields[i];
  378.                 if (field.IsLiteral) {
  379.                     object value = field.value;
  380.                     if (value is FunctionObject) {
  381.                         JSMemberField startMethod = field;
  382.                         while (true) {
  383.                             FunctionObject func = (FunctionObject)value;
  384.                             if (func.implementedIface != null)
  385.                                 break;
  386.                             this.CheckMethodDeclarationConsistency(func);
  387.                             if (field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly)
  388.                                 func.CheckCLSCompliance(checkCLSCompliance);
  389.                             field = field.nextOverload;
  390.                             if (field == null)
  391.                                 break;
  392.                             value = field.value;
  393.                         }
  394.                         continue;
  395.                     }
  396.                     else if (value is JSProperty) {
  397.                         continue;
  398.                     }
  399.                 }
  400.                 this.CheckFieldDeclarationConsistency(field);
  401.                 if (field.IsPublic || field.IsFamily || field.IsFamilyOrAssembly)
  402.                     field.CheckCLSCompliance(checkCLSCompliance);
  403.             }
  404.         }
  405.        
  406.         private void CheckMethodDeclarationConsistency(FunctionObject func)
  407.         {
  408.             if (func.isStatic && !func.isExpandoMethod)
  409.                 return;
  410.             //static methods do not clash with superclass methods
  411.             if (func.isConstructor)
  412.                 return;
  413.             //Constructors cannot clash with superclass members
  414.             object index = this.firstIndex[func.name];
  415.             if (index == null) {
  416.                 //There is no super class member with the same name as the function
  417.                 this.CheckThatMethodIsNotMarkedWithOverrideOrHide(func);
  418.                 if ((func.attributes & MethodAttributes.Final) != 0)
  419.                     func.attributes &= ~(MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
  420.                 return;
  421.             }
  422.             MemberInfo differentTypeOfMember = null;
  423.            
  424.             for (int i = (int)indexint n = this.superMembers.Length; i < n; i++) {
  425.                 MemberInfo member = this.superMembers[i] as MemberInfo;
  426.                 if (member == null)
  427.                     //if we do not get a MemberInfo we have already processed this superclass member and it matches another member of the current class
  428.                     continue;
  429.                 if (!member.Name.Equals(func.name))
  430.                     break;
  431.                 if (!this.CanSee(member))
  432.                     continue;
  433.                 if (member.MemberType != MemberTypes.Method) {
  434.                     //JScript does not allow overloading among different member types.
  435.                     //Unless there is a superclass method with the same signature as the method, we have to give an error
  436.                     differentTypeOfMember = member;
  437.                     continue;
  438.                 }
  439.                 if (func.isExpandoMethod) {
  440.                     differentTypeOfMember = member;
  441.                     break;
  442.                 }
  443.                 MethodInfo supmeth = (MethodInfo)member;
  444.                 if (func.implementedIface != null) {
  445.                     //Skip superclass methods that do not come from the appropriate interface
  446.                     if (supmeth is JSFieldMethod) {
  447.                         if (((JSFieldMethod)supmeth).EnclosingScope() != func.implementedIface)
  448.                             continue;
  449.                     }
  450.                     else {
  451.                         if (supmeth.DeclaringType != func.implementedIface)
  452.                             continue;
  453.                     }
  454.                 }
  455.                 if (Class.ParametersMatch(supmeth.GetParameters(), func.parameter_declarations)) {
  456.                     if (supmeth is JSWrappedMethod)
  457.                         supmeth = ((JSWrappedMethod)supmeth).method;
  458.                     if (func.noVersionSafeAttributeSpecified || (func.attributes & MethodAttributes.VtableLayoutMask) != MethodAttributes.NewSlot) {
  459.                         //Check consistency of implicit or explicit override (a hiding method may be inconsistent)
  460.                         this.CheckMatchingMethodForConsistency(supmeth, func, i, n);
  461.                     }
  462.                     return;
  463.                 }
  464.             }
  465.             if (differentTypeOfMember != null) {
  466.                 //Did not find a superclass method with the same signature, but did find a member with same name that was not a method
  467.                 //This is a no no for JScript unless the hide attribute has been specified
  468.                 if (func.noVersionSafeAttributeSpecified || (func.attributes & MethodAttributes.VtableLayoutMask) != MethodAttributes.NewSlot && !func.isExpandoMethod) {
  469.                     string supMemberName = this.GetFullNameFor(differentTypeOfMember);
  470.                     func.funcContext.HandleError(JSError.HidesParentMember, supMemberName, this.IsInTheSameCompilationUnit(differentTypeOfMember));
  471.                 }
  472.                 return;
  473.             }
  474.             //No matching method in superclass. Give an error if hide/override was specified
  475.             this.CheckThatMethodIsNotMarkedWithOverrideOrHide(func);
  476.             //Make final methods into non virtual
  477.             if ((func.attributes & MethodAttributes.Final) != 0)
  478.                 func.attributes &= ~(MethodAttributes.Virtual | MethodAttributes.NewSlot | MethodAttributes.Final);
  479.         }
  480.        
  481.         private void CheckMatchingMethodForConsistency(MethodInfo matchingMethod, FunctionObject func, int i, int n)
  482.         {
  483.             // return-type consistency - the return-type has to be the same
  484.             IReflect rir = func.ReturnType(null);
  485.             IReflect mrir = matchingMethod is JSFieldMethod ? ((JSFieldMethod)matchingMethod).func.ReturnType(null) : matchingMethod.ReturnType;
  486.             if (!rir.Equals(mrir)) {
  487.                 func.funcContext.HandleError(JSError.DifferentReturnTypeFromBase, func.name, true);
  488.                 return;
  489.             }
  490.            
  491.             //Special treatment for methods that implement interface methods
  492.             if (func.implementedIface != null) {
  493.                 func.implementedIfaceMethod = matchingMethod;
  494.                 this.superMembers[i] = func.name;
  495.                 //obliterate it so that it does not show up as unimplemented
  496.                 return;
  497.             }
  498.            
  499.             // visibility consistency - the visibility specification has to be the same
  500.             MethodAttributes visibility = func.attributes & MethodAttributes.MemberAccessMask;
  501.             if ((matchingMethod.Attributes & MethodAttributes.MemberAccessMask) != visibility)
  502.                 if ((matchingMethod.Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.FamORAssem || visibility != MethodAttributes.Family)
  503.                 //Allow Family to match FamORAssem
  504.                     func.funcContext.HandleError(JSError.CannotChangeVisibility);
  505.            
  506.             // hiding, overriding and layout consistency
  507.             // if i >= 0 after this, the base method is an overridden abstract method and steps should be taken to prevent a not implemented error
  508.             if (func.noVersionSafeAttributeSpecified) {
  509.                 // current method does not specify any attribute (i.e. hide or override)
  510.                 if (this.Engine.versionSafe) {
  511.                     //Give a message. The compiler option requires a method to say hide or override when there is a match.
  512.                     if ((matchingMethod.Attributes & MethodAttributes.Abstract) != 0) {
  513.                         // base is abstract
  514.                         func.funcContext.HandleError(JSError.HidesAbstractInBase, this.name + "." + func.name);
  515.                         func.attributes &= ~MethodAttributes.NewSlot;
  516.                         //Recover from error by overriding, it may be less bad than throwing a class load exception
  517.                     }
  518.                     else {
  519.                         func.funcContext.HandleError(JSError.NewNotSpecifiedInMethodDeclaration, this.IsInTheSameCompilationUnit(matchingMethod));
  520.                         i = -1;
  521.                     }
  522.                 }
  523.                 else {
  524.                     //No message, override if possible, otherwise hide
  525.                     if ((matchingMethod.Attributes & MethodAttributes.Virtual) == 0 || (matchingMethod.Attributes & MethodAttributes.Final) != 0) {
  526.                         // base is non virtual or final, hide
  527.                         i = -1;
  528.                     }
  529.                     else {
  530.                         func.attributes &= ~MethodAttributes.NewSlot;
  531.                         //override
  532.                         if ((matchingMethod.Attributes & MethodAttributes.Abstract) == 0)
  533.                             i = -1;
  534.                     }
  535.                 }
  536.             }
  537.             else {
  538.                 //Current method is marked override or hide
  539.                 if ((func.attributes & MethodAttributes.VtableLayoutMask) == MethodAttributes.ReuseSlot) {
  540.                     // current method specifies override
  541.                     if ((matchingMethod.Attributes & MethodAttributes.Virtual) == 0 || (matchingMethod.Attributes & MethodAttributes.Final) != 0) {
  542.                         // base is non virtual or final, hide
  543.                         func.funcContext.HandleError(JSError.MethodInBaseIsNotVirtual);
  544.                         i = -1;
  545.                     }
  546.                     else {
  547.                         func.attributes &= ~MethodAttributes.NewSlot;
  548.                         //override
  549.                         if ((matchingMethod.Attributes & MethodAttributes.Abstract) == 0)
  550.                             i = -1;
  551.                     }
  552.                 }
  553.                 else {
  554.                     // current method specifies hide
  555.                     Debug.Assert((func.attributes & MethodAttributes.VtableLayoutMask) == MethodAttributes.NewSlot);
  556.                     if ((matchingMethod.Attributes & MethodAttributes.Abstract) != 0) {
  557.                         // base is abstract
  558.                         func.funcContext.HandleError(JSError.HidesAbstractInBase, this.name + "." + func.name);
  559.                         func.attributes &= ~MethodAttributes.NewSlot;
  560.                         //Recover from error by overriding, it may be less bad than throwing a class load exception
  561.                     }
  562.                     else
  563.                         i = -1;
  564.                 }
  565.             }
  566.            
  567.             if (i >= 0) {
  568.                 //Overriding an abstract method. Take steps to prevent error messages.
  569.                 Debug.Assert((matchingMethod.Attributes & MethodAttributes.Abstract) != 0);
  570.                 this.superMembers[i] = func.name;
  571.                 //obliterate it so that it does not show up as unimplemented
  572.                 //Do likewise for any matching abstract members declared in less derived base classes
  573.                 for (int j = i + 1; j < n; j++) {
  574.                     //Most derived class is always first
  575.                     MemberInfo mem = this.superMembers[j] as MemberInfo;
  576.                     if (mem == null)
  577.                         continue;
  578.                     if (mem.Name != matchingMethod.Name)
  579.                         break;
  580.                     MethodInfo meth2 = mem as MethodInfo;
  581.                     if (meth2 == null)
  582.                         continue;
  583.                     if (meth2.IsAbstract && Class.ParametersMatch(meth2.GetParameters(), matchingMethod.GetParameters())) {
  584.                         IReflect rt = matchingMethod is JSFieldMethod ? ((JSFieldMethod)matchingMethod).ReturnIR() : matchingMethod.ReturnType;
  585.                         IReflect rt2 = meth2 is JSFieldMethod ? ((JSFieldMethod)meth2).ReturnIR() : meth2.ReturnType;
  586.                         if (rt == rt2)
  587.                             this.superMembers[j] = func.name;
  588.                     }
  589.                 }
  590.             }
  591.         }
  592.        
  593.         private void CheckThatAllAbstractSuperClassMethodsAreImplemented()
  594.         {
  595.             //By the time we get here all abstract superclass members that are implemented by this class are already replaced by
  596.             //their names in superMembers. What remains is to weed out those that are implemented by more derived base classes
  597.             //and then to complain about any that are left over.
  598.             for (int i = 0int n = this.superMembers.Length; i < n; i++) {
  599.                 object ob = this.superMembers[i];
  600.                 MethodInfo meth = ob as MethodInfo;
  601.                 if (meth != null) {
  602.                     if (!meth.IsAbstract)
  603.                         continue;
  604.                     //Check to see if implemented by a more derived base class
  605.                     for (int j = i - 1; j >= 0; j--) {
  606.                         object mem = this.superMembers[j];
  607.                         if (mem is MethodInfo) {
  608.                             MethodInfo meth2 = (MethodInfo)mem;
  609.                             if (meth2.Name != meth.Name)
  610.                                 break;
  611.                             if (!meth2.IsAbstract && Class.ParametersMatch(meth2.GetParameters(), meth.GetParameters())) {
  612.                                 IReflect rt = meth is JSFieldMethod ? ((JSFieldMethod)meth).ReturnIR() : meth.ReturnType;
  613.                                 IReflect rt2 = meth2 is JSFieldMethod ? ((JSFieldMethod)meth2).ReturnIR() : meth2.ReturnType;
  614.                                 if (rt == rt2) {
  615.                                     this.superMembers[i] = meth.Name;
  616.                                     goto noError;
  617.                                 }
  618.                             }
  619.                         }
  620.                     }
  621.                     //Nope, give an error (unless class is marked abstract, but not if the method comes from an interface)
  622.                     if (!this.isAbstract || (!this.isInterface && Class.DefinedOnInterface(meth))) {
  623.                         StringBuilder sig = new StringBuilder(meth.DeclaringType.ToString());
  624.                         sig.Append('.');
  625.                         sig.Append(meth.Name);
  626.                         sig.Append('(');
  627.                         ParameterInfo[] pars = meth.GetParameters();
  628.                         for (int j = 0int m = pars.Length; j < m; j++) {
  629.                             sig.Append(pars[j].ParameterType.FullName);
  630.                             if (j < m - 1)
  631.                                 sig.Append(", ");
  632.                         }
  633.                         sig.Append(")");
  634.                         if (meth.ReturnType != Typeob.Void) {
  635.                             sig.Append(" : ");
  636.                             sig.Append(meth.ReturnType.FullName);
  637.                         }
  638.                         this.context.HandleError(JSError.MustImplementMethod, sig.ToString());
  639.                         this.attributes |= TypeAttributes.Abstract;
  640.                         //Make the class compilable
  641.                     }
  642.                     //If the super class method comes from an interface, emit an abstract method that implements it
  643.                 }
  644.                 noError:
  645.                 ;
  646.             }
  647.         }
  648.        
  649.         private void CheckThatMethodIsNotMarkedWithOverrideOrHide(FunctionObject func)
  650.         {
  651.             if (func.noVersionSafeAttributeSpecified)
  652.                 return;
  653.             //It is marked override or hide, give an appropriate error
  654.             if ((func.attributes & MethodAttributes.VtableLayoutMask) == MethodAttributes.ReuseSlot)
  655.                 func.funcContext.HandleError(JSError.NoMethodInBaseToOverride);
  656.             else
  657.                 // current method specifies override
  658.                 // current method specifies hide
  659.                 func.funcContext.HandleError(JSError.NoMethodInBaseToNew);
  660.         }
  661.        
  662.         private static bool DefinedOnInterface(MethodInfo meth)
  663.         {
  664.             JSFieldMethod jsmeth = meth as JSFieldMethod;
  665.             if (jsmeth != null)
  666.                 return ((ClassScope)jsmeth.func.enclosing_scope).owner.isInterface;
  667.             return meth.DeclaringType.IsInterface;
  668.         }
  669.        
  670.         private void EmitILForINeedEngineMethods()
  671.         {
  672.             if (!this.needsEngine)
  673.                 return;
  674.             TypeBuilder classwriter = (TypeBuilder)this.classob.classwriter;
  675.             FieldBuilder backingField = classwriter.DefineField("vsa Engine", Typeob.VsaEngine, FieldAttributes.Private | FieldAttributes.NotSerialized);
  676.            
  677.             MethodBuilder getMeth = classwriter.DefineMethod("GetEngine", MethodAttributes.Private | MethodAttributes.Virtual, Typeob.VsaEngine, null);
  678.             ILGenerator il = getMeth.GetILGenerator();
  679.             il.Emit(OpCodes.Ldarg_0);
  680.             il.Emit(OpCodes.Ldfld, backingField);
  681.             il.Emit(OpCodes.Ldnull);
  682.             Label endif = il.DefineLabel();
  683.             il.Emit(OpCodes.Bne_Un_S, endif);
  684.             il.Emit(OpCodes.Ldarg_0);
  685.             if (this.body.Engine.doCRS)
  686.                 il.Emit(OpCodes.Ldsfld, CompilerGlobals.contextEngineField);
  687.             else {
  688.                 if (this.context.document.engine.PEFileKind == PEFileKinds.Dll) {
  689.                     il.Emit(OpCodes.Ldtoken, classwriter);
  690.                     il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngineWithType);
  691.                 }
  692.                 else
  693.                     il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngine);
  694.             }
  695.            
  696.             il.Emit(OpCodes.Stfld, backingField);
  697.             il.MarkLabel(endif);
  698.             il.Emit(OpCodes.Ldarg_0);
  699.             il.Emit(OpCodes.Ldfld, backingField);
  700.             il.Emit(OpCodes.Ret);
  701.             classwriter.DefineMethodOverride(getMeth, CompilerGlobals.getEngineMethod);
  702.            
  703.             MethodBuilder setMeth = classwriter.DefineMethod("SetEngine", MethodAttributes.Private | MethodAttributes.Virtual, Typeob.Void, new Type[] {Typeob.VsaEngine});
  704.             il = setMeth.GetILGenerator();
  705.             il.Emit(OpCodes.Ldarg_0);
  706.             il.Emit(OpCodes.Ldarg_1);
  707.             il.Emit(OpCodes.Stfld, backingField);
  708.             il.Emit(OpCodes.Ret);
  709.             classwriter.DefineMethodOverride(setMeth, CompilerGlobals.setEngineMethod);
  710.         }
  711.        
  712.         internal void EmitInitialCalls(ILGenerator il, MethodBase supcons, ParameterInfo[] pars, ASTList argAST, int callerParameterCount)
  713.         {
  714.             bool callFieldInitializer = true;
  715.             if (supcons != null) {
  716.                 il.Emit(OpCodes.Ldarg_0);
  717.                 int n = pars.Length;
  718.                 int m = argAST == null ? 0 : argAST.count;
  719.                 object[] tempArray = new object[n];
  720.                 for (int i = 0; i < n; i++) {
  721.                     AST actual = i < m ? argAST[i] : new ConstantWrapper(null, null);
  722.                     if (pars[i].ParameterType.IsByRef)
  723.                         tempArray[i] = actual.TranslateToILReference(il, pars[i].ParameterType.GetElementType());
  724.                     else {
  725.                         actual.TranslateToIL(il, pars[i].ParameterType);
  726.                         tempArray[i] = null;
  727.                     }
  728.                 }
  729.                 if (supcons is JSConstructor) {
  730.                     JSConstructor cons = (JSConstructor)supcons;
  731.                     callFieldInitializer = cons.GetClassScope() != this.classob;
  732.                     supcons = cons.GetConstructorInfo(this.compilerGlobals);
  733.                     //if cons belongs to a nested instance class, load the outer class instance on the stack
  734.                     if (cons.GetClassScope().outerClassField != null)
  735.                         Convert.EmitLdarg(il, (short)callerParameterCount);
  736.                 }
  737.                 il.Emit(OpCodes.Call, (ConstructorInfo)supcons);
  738.                 for (int i = 0; i < m; i++) {
  739.                     AST arg = argAST[i];
  740.                     if (arg is AddressOf && tempArray[i] != null) {
  741.                         Type argType = Convert.ToType(arg.InferType(null));
  742.                         arg.TranslateToILPreSet(il);
  743.                         il.Emit(OpCodes.Ldloc, (LocalBuilder)tempArray[i]);
  744.                         Convert.Emit(this, il, pars[i].ParameterType, argType);
  745.                         arg.TranslateToILSet(il);
  746.                     }
  747.                 }
  748.             }
  749.             if (this.classob.outerClassField != null) {
  750.                 il.Emit(OpCodes.Ldarg_0);
  751.                 Convert.EmitLdarg(il, (short)callerParameterCount);
  752.                 il.Emit(OpCodes.Stfld, this.classob.outerClassField);
  753.             }
  754.             if (callFieldInitializer) {
  755.                 il.Emit(OpCodes.Ldarg_0);
  756.                 il.Emit(OpCodes.Call, this.fieldInitializer);
  757.                 ((Block)(this.body)).TranslateToILInitOnlyInitializers(il);
  758.             }
  759.         }
  760.        
  761.         private void EnterNameIntoEnclosingScopeAndGetOwnField(AST id, bool isStatic)
  762.         {
  763.             if (((IActivationObject)this.enclosingScope).GetLocalField(this.name) != null) {
  764.                 id.context.HandleError(JSError.DuplicateName, true);
  765.                 this.name = this.name + " class";
  766.             }
  767.             FieldAttributes fieldAttrs = FieldAttributes.Literal;
  768.             switch (this.attributes & TypeAttributes.VisibilityMask) {
  769.                 case TypeAttributes.NestedAssembly:
  770.                     fieldAttrs |= FieldAttributes.Assembly;
  771.                     break;
  772.                 case TypeAttributes.NestedFamANDAssem:
  773.                     fieldAttrs |= FieldAttributes.FamANDAssem;
  774.                     break;
  775.                 case TypeAttributes.NestedFamily:
  776.                     fieldAttrs |= FieldAttributes.Family;
  777.                     break;
  778.                 case TypeAttributes.NestedFamORAssem:
  779.                     fieldAttrs |= FieldAttributes.FamORAssem;
  780.                     break;
  781.                 case TypeAttributes.NestedPrivate:
  782.                     fieldAttrs |= FieldAttributes.Private;
  783.                     break;
  784.                 default:
  785.                     fieldAttrs |= FieldAttributes.Public;
  786.                     break;
  787.             }
  788.             ScriptObject enclScope = this.enclosingScope;
  789.             while (enclScope is BlockScope)
  790.                 enclScope = enclScope.GetParent();
  791.             if (!(enclScope is GlobalScope) && !(enclScope is PackageScope) && !(enclScope is ClassScope)) {
  792.                 isStatic = false;
  793.                 if (this is EnumDeclaration)
  794.                     this.context.HandleError(JSError.EnumNotAllowed);
  795.                 else
  796.                     this.context.HandleError(JSError.ClassNotAllowed);
  797.             }
  798.             if (isStatic)
  799.                 fieldAttrs |= FieldAttributes.Static;
  800.             if (this.enclosingScope is ActivationObject) {
  801.                 if (this.enclosingScope is ClassScope) {
  802.                     if (this.name == ((ClassScope)this.enclosingScope).name) {
  803.                         context.HandleError(JSError.CannotUseNameOfClass);
  804.                         this.name = this.name + " nested class";
  805.                     }
  806.                 }
  807.                 this.ownField = ((ActivationObject)this.enclosingScope).AddNewField(this.name, this.classob, fieldAttrs);
  808.                 if (this.ownField is JSLocalField)
  809.                     ((JSLocalField)this.ownField).isDefined = true;
  810.             }
  811.             else
  812.                 this.ownField = ((StackFrame)this.enclosingScope).AddNewField(this.name, this.classob, fieldAttrs);
  813.             this.ownField.originalContext = id.context;
  814.         }
  815.        
  816.         internal override object Evaluate()
  817.         {
  818.             this.Globals.ScopeStack.GuardedPush(this.classob);
  819.             try {
  820.                 this.body.EvaluateStaticVariableInitializers();
  821.             }
  822.             finally {
  823.                 this.Globals.ScopeStack.Pop();
  824.             }
  825.             return new Completion();
  826.         }
  827.        
  828.         // generate the field containing the expando hashtable and the default indexer
  829.         private void GenerateGetEnumerator()
  830.         {
  831.             TypeBuilder classwriter = this.classob.GetTypeBuilder();
  832.             MethodBuilder getEnumerator = classwriter.DefineMethod("get enumerator", MethodAttributes.Private | MethodAttributes.Virtual, Typeob.IEnumerator, null);
  833.             ILGenerator il = getEnumerator.GetILGenerator();
  834.             il.Emit(OpCodes.Ldarg_0);
  835.             il.Emit(OpCodes.Call, this.getHashTableMethod);
  836.             il.Emit(OpCodes.Call, CompilerGlobals.hashTableGetEnumerator);
  837.             il.Emit(OpCodes.Ret);
  838.             classwriter.DefineMethodOverride(getEnumerator, CompilerGlobals.getEnumeratorMethod);
  839.         }
  840.        
  841.         // generate the field containing the expando hashtable and the default indexer
  842.         private void GetExpandoFieldGetter(TypeBuilder classwriter)
  843.         {
  844.             if (this.expandoItemProp == null) {
  845.                 this.expandoItemProp = classwriter.DefineProperty("Item", PropertyAttributes.None, Typeob.Object, new Type[] {Typeob.String});
  846.                
  847.                 // if it is an expando, generate a SimpleHashtable field called 'expando table'
  848.                 FieldInfo expandoTableField = classwriter.DefineField("expando table", Typeob.SimpleHashtable, FieldAttributes.Private);
  849.                
  850.                 // generate code for a hashtable getter. It will initialize the hashtable if null
  851.                 this.getHashTableMethod = classwriter.DefineMethod("get expando table", MethodAttributes.Private, Typeob.SimpleHashtable, null);
  852.                 ILGenerator il = this.getHashTableMethod.GetILGenerator();
  853.                 il.Emit(OpCodes.Ldarg_0);
  854.                 il.Emit(OpCodes.Ldfld, expandoTableField);
  855.                 il.Emit(OpCodes.Ldnull);
  856.                 Label endif = il.DefineLabel();
  857.                 il.Emit(OpCodes.Bne_Un_S, endif);
  858.                 il.Emit(OpCodes.Ldarg_0);
  859.                 il.Emit(OpCodes.Ldc_I4_8);
  860.                 il.Emit(OpCodes.Newobj, CompilerGlobals.hashtableCtor);
  861.                 il.Emit(OpCodes.Stfld, expandoTableField);
  862.                 il.MarkLabel(endif);
  863.                 il.Emit(OpCodes.Ldarg_0);
  864.                 il.Emit(OpCodes.Ldfld, expandoTableField);
  865.                 il.Emit(OpCodes.Ret);
  866.             }
  867.         }
  868.        
  869.         // can be called from outside this class (JSExpandoIndexerMethod)
  870.         internal MethodInfo GetExpandoIndexerGetter()
  871.         {
  872.             if (this.getItem == null) {
  873.                 TypeBuilder classwriter = this.classob.GetTypeBuilder();
  874.                 this.GetExpandoFieldGetter(classwriter);
  875.                 // create the getter
  876.                 this.getItem = classwriter.DefineMethod("get_Item", MethodAttributes.Public | MethodAttributes.SpecialName, Typeob.Object, new Type[] {Typeob.String});
  877.                 ILGenerator il = this.getItem.GetILGenerator();
  878.                 il.Emit(OpCodes.Ldarg_0);
  879.                 il.Emit(OpCodes.Call, this.getHashTableMethod);
  880.                 il.Emit(OpCodes.Ldarg_1);
  881.                 il.Emit(OpCodes.Call, CompilerGlobals.hashtableGetItem);
  882.                 il.Emit(OpCodes.Dup);
  883.                 Label endif = il.DefineLabel();
  884.                 il.Emit(OpCodes.Brtrue_S, endif);
  885.                 il.Emit(OpCodes.Pop);
  886.                 il.Emit(OpCodes.Ldsfld, CompilerGlobals.missingField);
  887.                 il.MarkLabel(endif);
  888.                 il.Emit(OpCodes.Ret);
  889.                 this.expandoItemProp.SetGetMethod(this.getItem);
  890.             }
  891.             return this.getItem;
  892.         }
  893.        
  894.         // can be called from outside this class (JSExpandoIndexerMethod)
  895.         internal MethodInfo GetExpandoIndexerSetter()
  896.         {
  897.             if (this.setItem == null) {
  898.                 TypeBuilder classwriter = this.classob.GetTypeBuilder();
  899.                 this.GetExpandoFieldGetter(classwriter);
  900.                 // create the setter
  901.                 this.setItem = classwriter.DefineMethod("set_Item", MethodAttributes.Public | MethodAttributes.SpecialName, Typeob.Void, new Type[2] {Typeob.String, Typeob.Object});
  902.                 ILGenerator il = this.setItem.GetILGenerator();
  903.                 il.Emit(OpCodes.Ldarg_0);
  904.                 il.Emit(OpCodes.Call, this.getHashTableMethod);
  905.                 il.Emit(OpCodes.Ldarg_2);
  906.                 il.Emit(OpCodes.Ldsfld, CompilerGlobals.missingField);
  907.                 Label endif = il.DefineLabel();
  908.                 il.Emit(OpCodes.Beq_S, endif);
  909.                 il.Emit(OpCodes.Ldarg_1);
  910.                 il.Emit(OpCodes.Ldarg_2);
  911.                 il.Emit(OpCodes.Call, CompilerGlobals.hashtableSetItem);
  912.                 il.Emit(OpCodes.Ret);
  913.                 il.MarkLabel(endif);
  914.                 il.Emit(OpCodes.Ldarg_1);
  915.                 il.Emit(OpCodes.Call, CompilerGlobals.hashtableRemove);
  916.                 il.Emit(OpCodes.Ret);
  917.                 this.expandoItemProp.SetSetMethod(this.setItem);
  918.             }
  919.             return this.setItem;
  920.         }
  921.        
  922.         private void GetExpandoDeleteMethod()
  923.         {
  924.             TypeBuilder tb = this.classob.GetTypeBuilder();
  925.             MethodBuilder mb = this.deleteOpMethod = tb.DefineMethod("op_Delete", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, Typeob.Boolean, new Type[2] {tb, Typeob.ArrayOfObject});
  926.             ParameterBuilder pb = mb.DefineParameter(2, (ParameterAttributes)0, null);
  927.             pb.SetCustomAttribute(new CustomAttributeBuilder(Typeob.ParamArrayAttribute.GetConstructor(Type.EmptyTypes), new object[] {}));
  928.             ILGenerator il = mb.GetILGenerator();
  929.             il.Emit(OpCodes.Ldarg_0);
  930.             il.Emit(OpCodes.Call, this.getHashTableMethod);
  931.             il.Emit(OpCodes.Ldarg_1);
  932.             il.Emit(OpCodes.Dup);
  933.             il.Emit(OpCodes.Ldlen);
  934.             il.Emit(OpCodes.Ldc_I4_1);
  935.             il.Emit(OpCodes.Sub);
  936.             il.Emit(OpCodes.Ldelem_Ref);
  937.             il.Emit(OpCodes.Call, CompilerGlobals.hashtableRemove);
  938.             il.Emit(OpCodes.Ldc_I4_1);
  939.             il.Emit(OpCodes.Ret);
  940.         }
  941.        
  942.         private string GetFullNameFor(MemberInfo supMem)
  943.         {
  944.             string supMemberName;
  945.             if (supMem is JSField)
  946.                 supMemberName = ((JSField)supMem).GetClassFullName();
  947.             else if (supMem is JSConstructor)
  948.                 supMemberName = ((JSConstructor)supMem).GetClassFullName();
  949.             else if (supMem is JSMethod)
  950.                 supMemberName = ((JSMethod)supMem).GetClassFullName();
  951.             else if (supMem is JSProperty)
  952.                 supMemberName = ((JSProperty)supMem).GetClassFullName();
  953.             else if (supMem is JSWrappedProperty)
  954.                 supMemberName = ((JSWrappedProperty)supMem).GetClassFullName();
  955.             else
  956.                 supMemberName = ((MemberInfo)supMem).DeclaringType.FullName;
  957.             return supMemberName + "." + ((MemberInfo)supMem).Name;
  958.         }
  959.        
  960.         internal MemberInfo[] GetInterfaceMember(string name)
  961.         {
  962.             this.PartiallyEvaluate();
  963.             MemberInfo[] result;
  964.             if (this.isInterface) {
  965.                 result = this.classob.GetMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
  966.                 if (result != null && result.Length > 0)
  967.                     return result;
  968.             }
  969.             foreach (TypeExpression ifaceExpr in this.interfaces) {
  970.                 IReflect ir = ifaceExpr.ToIReflect();
  971.                 result = ir.GetMember(name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
  972.                 if (result != null && result.Length > 0)
  973.                     return result;
  974.             }
  975.             return new MemberInfo[0];
  976.         }
  977.        
  978.         private void GetIRForSuperType()
  979.         {
  980.             IReflect supIR = this.superIR = Typeob.Object;
  981.             if (this.superTypeExpression != null) {
  982.                 this.superTypeExpression.PartiallyEvaluate();
  983.                 supIR = this.superIR = this.superTypeExpression.ToIReflect();
  984.             }
  985.             Type supType = supIR as Type;
  986.             if (supType != null) {
  987.                 if (supType.IsSealed || supType.IsInterface || supType == Typeob.ValueType || supType == Typeob.ArrayObject) {
  988.                     if (this.superTypeExpression.Evaluate() is Namespace)
  989.                         this.superTypeExpression.context.HandleError(JSError.NeedType);
  990.                     else
  991.                         this.superTypeExpression.context.HandleError(JSError.TypeCannotBeExtended, supType.FullName);
  992.                     this.superTypeExpression = null;
  993.                     this.superIR = Typeob.Object;
  994.                 }
  995.                 else if (Typeob.INeedEngine.IsAssignableFrom(supType))
  996.                     this.needsEngine = false;
  997.             }
  998.             else if (supIR is ClassScope) {
  999.                 if (((ClassScope)supIR).owner.IsASubClassOf(this)) {
  1000.                     this.superTypeExpression.context.HandleError(JSError.CircularDefinition);
  1001.                     this.superTypeExpression = null;
  1002.                     this.superIR = Typeob.Object;
  1003.                 }
  1004.                 else {
  1005.                     this.needsEngine = false;
  1006.                     this.superClass = ((ClassScope)supIR).owner;
  1007.                     if ((this.superClass.attributes & TypeAttributes.Sealed) != 0) {
  1008.                         this.superTypeExpression.context.HandleError(JSError.TypeCannotBeExtended, this.superClass.name);
  1009.                         this.superClass.attributes &= ~TypeAttributes.Sealed;
  1010.                         this.superTypeExpression = null;
  1011.                     }
  1012.                     else if (this.superClass.isInterface) {
  1013.                         this.superTypeExpression.context.HandleError(JSError.TypeCannotBeExtended, this.superClass.name);
  1014.                         this.superIR = Typeob.Object;
  1015.                         this.superTypeExpression = null;
  1016.                     }
  1017.                 }
  1018.             }
  1019.             else {
  1020.                 this.superTypeExpression.context.HandleError(JSError.TypeCannotBeExtended);
  1021.                 this.superIR = Typeob.Object;
  1022.                 this.superTypeExpression = null;
  1023.             }
  1024.         }
  1025.        
  1026.         private void GetStartIndexForEachName()
  1027.         {
  1028.             SimpleHashtable firstIndex = new SimpleHashtable(32);
  1029.             string lastName = null;
  1030.             for (int i = 0int n = this.superMembers.Length; i < n; i++) {
  1031.                 string name = ((MemberInfo)this.superMembers[i]).Name;
  1032.                 if (name != lastName)
  1033.                     firstIndex[lastName = name] = i;
  1034.             }
  1035.             this.firstIndex = firstIndex;
  1036.         }
  1037.        
  1038.         internal ConstructorInfo GetSuperConstructor(IReflect[] argIRs)
  1039.         {
  1040.             object val = null;
  1041.             if (this.superTypeExpression != null)
  1042.                 val = this.superTypeExpression.Evaluate();
  1043.             else
  1044.                 val = Typeob.Object;
  1045.             if (val is ClassScope)
  1046.                 return JSBinder.SelectConstructor(((ClassScope)val).constructors, argIRs);
  1047.             else
  1048.                 return JSBinder.SelectConstructor(((Type)val).GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance), argIRs);
  1049.         }
  1050.        
  1051.         private void GetSuperTypeMembers()
  1052.         {
  1053.             SuperTypeMembersSorter sorter = new SuperTypeMembersSorter();
  1054.             IReflect ir = this.superIR;
  1055.             //Add members on superclasses
  1056.             while (ir != null) {
  1057.                 sorter.Add(ir.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly));
  1058.                 if (ir is Type) {
  1059.                     ir = ((Type)ir).BaseType;
  1060.                 }
  1061.                 else {
  1062.                     ir = ((ClassScope)ir).GetSuperType();
  1063.                 }
  1064.             }
  1065.             //Add any implicit interfaces to the end of the explicit list of interfaces
  1066.             ArrayList implicitInterfaces = new ArrayList();
  1067.             int n = this.interfaces.Length;
  1068.             IReflect[] explicitInterfaces = new IReflect[n];
  1069.             for (int i = 0; i < n; i++) {
  1070.                 IReflect iface = explicitInterfaces[i] = this.interfaces[i].ToIReflect();
  1071.                 Type t = iface as Type;
  1072.                 bool isInterface;
  1073.                 if (t != null)
  1074.                     isInterface = t.IsInterface;
  1075.                 else {
  1076.                     ClassScope csc = (ClassScope)iface;
  1077.                     isInterface = csc.owner.isInterface;
  1078.                 }
  1079.                 if (!isInterface)
  1080.                     this.interfaces[i].context.HandleError(JSError.NeedInterface);
  1081.             }
  1082.             foreach (IReflect iface in explicitInterfaces)
  1083.                 this.AddImplicitInterfaces(iface, explicitInterfaces, implicitInterfaces);
  1084.             for (int i = 0; i < implicitInterfaces.Count; i++) {
  1085.                 IReflect iface = (IReflect)implicitInterfaces[i];
  1086.                 this.AddImplicitInterfaces(iface, explicitInterfaces, implicitInterfaces);
  1087.             }
  1088.             int m = implicitInterfaces.Count;
  1089.             if (m > 0) {
  1090.                 TypeExpression[] newInterfaces = new TypeExpression[n + m];
  1091.                 for (int i = 0; i < n; i++)
  1092.                     newInterfaces[i] = this.interfaces[i];
  1093.                 for (int i = 0; i < m; i++)
  1094.                     newInterfaces[i + n] = new TypeExpression(new ConstantWrapper(implicitInterfaces[i], null));
  1095.                 this.interfaces = newInterfaces;
  1096.             }
  1097.             //Add members on interfaces implemented by the class. Also check for circular definition;
  1098.             foreach (TypeExpression ifaceExpr in this.interfaces) {
  1099.                 ClassScope ifcsc = ifaceExpr.ToIReflect() as ClassScope;
  1100.                 if (ifcsc != null && ifcsc.owner.ImplementsInterface(this.classob)) {
  1101.                     this.context.HandleError(JSError.CircularDefinition);
  1102.                     this.interfaces = new TypeExpression[0];
  1103.                     break;
  1104.                 }
  1105.                 sorter.Add(ifaceExpr.ToIReflect().GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
  1106.             }
  1107.             //Add unimplemented members on interfaces implemented by abstract superclasses
  1108.             ir = this.superIR;
  1109.             while (ir != null) {
  1110.                 Type type = ir as Type;
  1111.                 if (type != null) {
  1112.                     if (!type.IsAbstract)
  1113.                         break;
  1114.                     Class.GetUnimplementedInferfaceMembersFor(type, sorter);
  1115.                     ir = type.BaseType;
  1116.                 }
  1117.                 else {
  1118.                     ClassScope csc = (ClassScope)ir;
  1119.                     if (!csc.owner.isAbstract)
  1120.                         break;
  1121.                     csc.owner.GetUnimplementedInferfaceMembers(sorter);
  1122.                     ir = null;
  1123.                 }
  1124.             }
  1125.             this.superMembers = sorter.GetMembers();
  1126.         }
  1127.        
  1128.         internal TypeBuilder GetTypeBuilder()
  1129.         {
  1130.             return (TypeBuilder)this.GetTypeBuilderOrEnumBuilder();
  1131.         }
  1132.        
  1133.         internal virtual Type GetTypeBuilderOrEnumBuilder()
  1134.         {
  1135.             if (this.classob.classwriter != null)
  1136.                 return this.classob.classwriter;
  1137.             if (!this.isAlreadyPartiallyEvaluated)
  1138.                 this.PartiallyEvaluate();
  1139.             Type superType = null;
  1140.             if (this.superTypeExpression != null)
  1141.                 superType = this.superTypeExpression.ToType();
  1142.             else
  1143.                 superType = this.isInterface ? null : Typeob.Object;
  1144.             int offset = (this.needsEngine ? 1 : 0) + (this.generateCodeForExpando ? 1 : 0);
  1145.             int n = this.interfaces.Length + offset;
  1146.             Type[] interfaces = new Type[n];
  1147.             for (int i = offset; i < n; i++)
  1148.                 interfaces[i] = this.interfaces[i - offset].ToType();
  1149.             if (this.needsEngine)
  1150.                 interfaces[--offset] = Typeob.INeedEngine;
  1151.             if (this.generateCodeForExpando)
  1152.                 interfaces[--offset] = Typeob.IEnumerable;
  1153.            
  1154.             TypeBuilder result;
  1155.             if (this.enclosingScope is ClassScope) {
  1156.                 if ((result = (TypeBuilder)this.classob.classwriter) == null) {
  1157.                     TypeBuilder enclosingClass = ((ClassScope)this.enclosingScope).owner.GetTypeBuilder();
  1158.                     if (this.classob.classwriter != null)
  1159.                         return this.classob.classwriter;
  1160.                     result = enclosingClass.DefineNestedType(this.name, this.attributes, superType, interfaces);
  1161.                     this.classob.classwriter = result;
  1162.                     if (!this.isStatic && !this.isInterface)
  1163.                         this.classob.outerClassField = result.DefineField("outer class instance", enclosingClass, FieldAttributes.Private);
  1164.                 }
  1165.             }
  1166.             else {
  1167.                 string scopeName = ((ActivationObject)this.enclosingScope).GetName();
  1168.                 if (scopeName == null) {
  1169.                     VsaEngine engine = this.context.document.engine;
  1170.                     if (engine != null && engine.genStartupClass)
  1171.                         scopeName = engine.RootNamespace;
  1172.                 }
  1173.                 if ((result = (TypeBuilder)this.classob.classwriter) == null) {
  1174.                     string typeName = this.name;
  1175.                     if (scopeName != null)
  1176.                         typeName = scopeName + "." + typeName;
  1177.                     if (typeName.Length >= 1024) {
  1178.                         this.context.HandleError(JSError.TypeNameTooLong, typeName);
  1179.                         typeName = "bad type name " + badTypeNameCount.ToString(CultureInfo.InvariantCulture);
  1180.                         badTypeNameCount++;
  1181.                     }
  1182.                     result = compilerGlobals.module.DefineType(typeName, this.attributes, superType, interfaces);
  1183.                     this.classob.classwriter = result;
  1184.                 }
  1185.             }
  1186.             // deal with custom attributes
  1187.             if (this.customAttributes != null) {
  1188.                 CustomAttributeBuilder[] custAtt = this.customAttributes.GetCustomAttributeBuilders(false);
  1189.                 for (int j = 0; j < custAtt.Length; j++) {
  1190.                     result.SetCustomAttribute(custAtt[j]);
  1191.                 }
  1192.             }
  1193.             if (this.clsCompliance == CLSComplianceSpec.CLSCompliant)
  1194.                 result.SetCustomAttribute(new CustomAttributeBuilder(CompilerGlobals.clsCompliantAttributeCtor, new object[] {true}));
  1195.             else if (this.clsCompliance == CLSComplianceSpec.NonCLSCompliant)
  1196.                 result.SetCustomAttribute(new CustomAttributeBuilder(CompilerGlobals.clsCompliantAttributeCtor, new object[] {false}));
  1197.             if (this.generateCodeForExpando)
  1198.                 result.SetCustomAttribute(new CustomAttributeBuilder(CompilerGlobals.defaultMemberAttributeCtor, new object[] {"Item"}));
  1199.            
  1200.             //Define the class fields
  1201.             for (int i = 0int m = this.fields.Length; i < m; i++) {
  1202.                 JSMemberField field = this.fields[i];
  1203.                 if (field.IsLiteral) {
  1204.                     object value = field.value;
  1205.                     if (value is JSProperty) {
  1206.                         JSProperty prop = (JSProperty)value;
  1207.                         ParameterInfo[] pars = prop.GetIndexParameters();
  1208.                         int np = pars.Length;
  1209.                         Type[] ptypes = new Type[np];
  1210.                         for (int j = 0; j < np; j++)
  1211.                             ptypes[j] = pars[j].ParameterType;
  1212.                         PropertyBuilder pb = prop.metaData = result.DefineProperty(field.Name, prop.Attributes, prop.PropertyType, ptypes);
  1213.                         if (prop.getter != null) {
  1214.                             CustomAttributeList cal = ((JSFieldMethod)prop.getter).func.customAttributes;
  1215.                             if (cal != null) {
  1216.                                 CustomAttributeBuilder[] custAttrs = cal.GetCustomAttributeBuilders(true);
  1217.                                 foreach (CustomAttributeBuilder cb in custAttrs)
  1218.                                     pb.SetCustomAttribute(cb);
  1219.                             }
  1220.                             pb.SetGetMethod((MethodBuilder)prop.getter.GetMethodInfo(compilerGlobals));
  1221.                         }
  1222.                         if (prop.setter != null) {
  1223.                             CustomAttributeList cal = ((JSFieldMethod)prop.setter).func.customAttributes;
  1224.                             if (cal != null) {
  1225.                                 CustomAttributeBuilder[] custAttrs = cal.GetCustomAttributeBuilders(true);
  1226.                                 foreach (CustomAttributeBuilder cb in custAttrs)
  1227.                                     pb.SetCustomAttribute(cb);
  1228.                             }
  1229.                             pb.SetSetMethod((MethodBuilder)prop.setter.GetMethodInfo(compilerGlobals));
  1230.                         }
  1231.                         continue;
  1232.                     }
  1233.                     else if (value is ClassScope) {
  1234.                         ((ClassScope)value).GetTypeBuilderOrEnumBuilder();
  1235.                     }
  1236.                     else if (Convert.GetTypeCode(value) != TypeCode.Object) {
  1237.                         FieldBuilder fb = result.DefineField(field.Name, field.FieldType, field.Attributes);
  1238.                         fb.SetConstant(field.value);
  1239.                         field.metaData = fb;
  1240.                         field.WriteCustomAttribute(this.Engine.doCRS);
  1241.                         continue;
  1242.                     }
  1243.                     else if (value is FunctionObject) {
  1244.                         FunctionObject func = (FunctionObject)value;
  1245.                         if (func.isExpandoMethod) {
  1246.                             field.metaData = result.DefineField(field.Name, Typeob.ScriptFunction, field.Attributes & ~(FieldAttributes.Literal | FieldAttributes.Static));
  1247.                             func.isStatic = false;
  1248.                         }
  1249.                         if (this.isInterface)
  1250.                             do {
  1251.                                 func.GetMethodInfo(compilerGlobals);
  1252.                                 field = field.nextOverload;
  1253.                                 if (field == null)
  1254.                                     break;
  1255.                                 func = (FunctionObject)field.value;
  1256.                             }
  1257.                             while (true);
  1258.                     }
  1259.                     continue;
  1260.                 }
  1261.                 field.metaData = result.DefineField(field.Name, field.FieldType, field.Attributes);
  1262.                 field.WriteCustomAttribute(this.Engine.doCRS);
  1263.             }
  1264.            
  1265.             return result;
  1266.         }
  1267.        
  1268.         private void GetUnimplementedInferfaceMembers(SuperTypeMembersSorter sorter)
  1269.         {
  1270.             for (int i = 0int n = this.superMembers.Length; i < n; i++) {
  1271.                 MethodInfo meth = this.superMembers[i] as MethodInfo;
  1272.                 if (meth != null && meth.DeclaringType.IsInterface)
  1273.                     sorter.Add(meth);
  1274.             }
  1275.             return;
  1276.         }
  1277.        
  1278.         private static void GetUnimplementedInferfaceMembersFor(Type type, SuperTypeMembersSorter sorter)
  1279.         {
  1280.             foreach (Type iface in type.GetInterfaces()) {
  1281.                 InterfaceMapping imap = type.GetInterfaceMap(iface);
  1282.                 MethodInfo[] interfaceMethods = imap.InterfaceMethods;
  1283.                 MethodInfo[] targetMethods = imap.TargetMethods;
  1284.                 for (int i = 0int n = interfaceMethods.Length; i < n; i++)
  1285.                     if (targetMethods[i] == null || targetMethods[i].IsAbstract)
  1286.                         sorter.Add(interfaceMethods[i]);
  1287.             }
  1288.         }
  1289.        
  1290.         internal bool ImplementsInterface(IReflect iface)
  1291.         {
  1292.             foreach (TypeExpression t in this.interfaces) {
  1293.                 IReflect ir = t.ToIReflect();
  1294.                 if (ir == iface)
  1295.                     return true;
  1296.                 if (ir is ClassScope && ((ClassScope)ir).ImplementsInterface(iface))
  1297.                     return true;
  1298.                 if (ir is Type && iface is Type && ((Type)iface).IsAssignableFrom((Type)ir))
  1299.                     return true;
  1300.             }
  1301.             return false;
  1302.         }
  1303.        
  1304.         private bool IsASubClassOf(Class cl)
  1305.         {
  1306.             if (this.superTypeExpression != null) {
  1307.                 this.superTypeExpression.PartiallyEvaluate();
  1308.                 IReflect supertype = this.superTypeExpression.ToIReflect();
  1309.                 if (supertype is ClassScope) {
  1310.                     Class superclass = ((ClassScope)supertype).owner;
  1311.                     if (superclass == cl)
  1312.                         return true;
  1313.                     else
  1314.                         return superclass.IsASubClassOf(cl);
  1315.                 }
  1316.             }
  1317.             return false;
  1318.         }
  1319.        
  1320.         internal bool IsCustomAttribute()
  1321.         {
  1322.             this.GetIRForSuperType();
  1323.             if (this.superIR != Typeob.Attribute)
  1324.                 return false;
  1325.             if (this.customAttributes == null)
  1326.                 return false;
  1327.             this.customAttributes.PartiallyEvaluate();
  1328.             if (this.validOn == 0)
  1329.                 return false;
  1330.             return true;
  1331.         }
  1332.        
  1333.         internal bool IsExpando()
  1334.         {
  1335.             if (this.hasAlreadyBeenAskedAboutExpando)
  1336.                 return this.isExpando;
  1337.             if (this.customAttributes != null) {
  1338.                 this.customAttributes.PartiallyEvaluate();
  1339.                 if (this.customAttributes.GetAttribute(Typeob.Expando) != null)
  1340.                     this.generateCodeForExpando = this.isExpando = true;
  1341.             }
  1342.             bool superClassIsExpando = false;
  1343.             this.GetIRForSuperType();
  1344.             ClassScope csc = this.superIR as ClassScope;
  1345.             if (csc != null) {
  1346.                 csc.owner.PartiallyEvaluate();
  1347.                 if (csc.owner.IsExpando())
  1348.                     this.isExpando = superClassIsExpando = true;
  1349.             }
  1350.             else {
  1351.                 if (CustomAttribute.IsDefined((Type)this.superIR, typeof(Expando), true))
  1352.                     this.isExpando = superClassIsExpando = true;
  1353.             }
  1354.             this.hasAlreadyBeenAskedAboutExpando = true;
  1355.             if (this.generateCodeForExpando)
  1356.                 this.CheckIfOKToGenerateCodeForExpando(superClassIsExpando);
  1357.             if (this.isExpando) {
  1358.                 this.classob.noExpando = false;
  1359.                 return true;
  1360.             }
  1361.             return false;
  1362.         }
  1363.        
  1364.         private bool IsInTheSameCompilationUnit(MemberInfo member)
  1365.         {
  1366.             return member is JSField || member is JSMethod;
  1367.         }
  1368.        
  1369.         private bool IsInTheSamePackage(MemberInfo member)
  1370.         {
  1371.             if (member is JSMethod || member is JSField) {
  1372.                 PackageScope memberPackage = null;
  1373.                 if (member is JSMethod)
  1374.                     memberPackage = ((JSMethod)member).GetPackage();
  1375.                 else if (member is JSConstructor)
  1376.                     memberPackage = ((JSConstructor)member).GetPackage();
  1377.                 else
  1378.                     memberPackage = ((JSField)member).GetPackage();
  1379.                 PackageScope currentPackage = this.classob.GetPackage();
  1380.                 return currentPackage == memberPackage;
  1381.             }
  1382.             else
  1383.                 return false;
  1384.         }
  1385.        
  1386.         internal bool IsStatic {
  1387.             get { return (this.isStatic || !(this.enclosingScope is ClassScope)); }
  1388.         }
  1389.        
  1390.         protected bool NeedsToBeCheckedForCLSCompliance()
  1391.         {
  1392.             bool result = false;
  1393.             this.clsCompliance = CLSComplianceSpec.NotAttributed;
  1394.             if (this.customAttributes != null) {
  1395.                 CustomAttribute clsAttr = this.customAttributes.GetAttribute(Typeob.CLSCompliantAttribute);
  1396.                 if (clsAttr != null) {
  1397.                     this.clsCompliance = clsAttr.GetCLSComplianceValue();
  1398.                     result = this.clsCompliance == CLSComplianceSpec.CLSCompliant;
  1399.                     this.customAttributes.Remove(clsAttr);
  1400.                 }
  1401.             }
  1402.             if (this.clsCompliance == CLSComplianceSpec.CLSCompliant && !this.Engine.isCLSCompliant)
  1403.                 this.context.HandleError(JSError.TypeAssemblyCLSCompliantMismatch);
  1404.             if (this.clsCompliance == CLSComplianceSpec.NotAttributed && (this.attributes & TypeAttributes.Public) != 0)
  1405.                 result = Engine.isCLSCompliant;
  1406.             return result;
  1407.         }
  1408.        
  1409.         static internal bool ParametersMatch(ParameterInfo[] suppars, ParameterInfo[] pars)
  1410.         {
  1411.             if (suppars.Length != pars.Length)
  1412.                 return false;
  1413.             for (int i = 0int n = pars.Length; i < n; i++) {
  1414.                 IReflect spir = suppars[i] is ParameterDeclaration ? ((ParameterDeclaration)suppars[i]).ParameterIReflect : suppars[i].ParameterType;
  1415.                 IReflect pir = pars[i] is ParameterDeclaration ? ((ParameterDeclaration)pars[i]).ParameterIReflect : pars[i].ParameterType;
  1416.                 if (!pir.Equals(spir))
  1417.                     return false;
  1418.             }
  1419.             return true;
  1420.         }
  1421.        
  1422.         internal override AST PartiallyEvaluate()
  1423.         {
  1424.             if (this.isAlreadyPartiallyEvaluated)
  1425.                 return this;
  1426.             this.isAlreadyPartiallyEvaluated = true;
  1427.             this.IsExpando();
  1428.             //Evaluate the custom attributes, run up the inheritance chain and add expando property if necessary
  1429.             this.classob.SetParent(new WithObject(this.enclosingScope, this.superIR, true));
  1430.             Globals.ScopeStack.Push(this.classob);
  1431.             try {
  1432.                 this.body.PartiallyEvaluate();
  1433.                 if (this.implicitDefaultConstructor != null)
  1434.                     this.implicitDefaultConstructor.PartiallyEvaluate();
  1435.             }
  1436.             finally {
  1437.                 Globals.ScopeStack.Pop();
  1438.             }
  1439.             foreach (JSMemberField field in this.fields)
  1440.                 field.CheckOverloadsForDuplicates();
  1441.             this.CheckIfValidExtensionOfSuperType();
  1442.             this.CheckThatAllAbstractSuperClassMethodsAreImplemented();
  1443.             return this;
  1444.         }
  1445.        
  1446.         private void SetAccessibility(FieldAttributes attributes)
  1447.         {
  1448.             FieldAttributes accessibility = attributes & FieldAttributes.FieldAccessMask;
  1449.             if (this.enclosingScope is ClassScope) {
  1450.                 if (accessibility == FieldAttributes.Public)
  1451.                     this.attributes |= TypeAttributes.NestedPublic;
  1452.                 else if (accessibility == FieldAttributes.Family)
  1453.                     this.attributes |= TypeAttributes.NestedFamily;
  1454.                 else if (accessibility == FieldAttributes.Assembly)
  1455.                     this.attributes |= TypeAttributes.NestedAssembly;
  1456.                 else if (accessibility == FieldAttributes.Private)
  1457.                     this.attributes |= TypeAttributes.NestedPrivate;
  1458.                 else if (accessibility == FieldAttributes.FamORAssem)
  1459.                     this.attributes |= TypeAttributes.NestedFamORAssem;
  1460.                 else
  1461.                     this.attributes |= TypeAttributes.NestedPublic;
  1462.             }
  1463.             else {
  1464.                 if (accessibility == FieldAttributes.Public || 0 == (int)accessibility)
  1465.                     this.attributes |= TypeAttributes.Public;
  1466.             }
  1467.         }
  1468.        
  1469.         private void SetupConstructors()
  1470.         {
  1471.             MemberInfo[] consmem = classob.GetMember(this.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly);
  1472.             //See if the class has a member with the name of the class
  1473.             if (consmem == null) {
  1474.                 this.AllocateImplicitDefaultConstructor();
  1475.                 FieldInfo field = this.classob.AddNewField(this.name, this.implicitDefaultConstructor, FieldAttributes.Literal);
  1476.                 this.classob.constructors = new ConstructorInfo[] {new JSConstructor(this.implicitDefaultConstructor)};
  1477.             }
  1478.             else {
  1479.                 MemberInfo cmem0 = null;
  1480.                 foreach (MemberInfo cmem in consmem) {
  1481.                     if (cmem is JSFieldMethod) {
  1482.                         FunctionObject cons = ((JSFieldMethod)cmem).func;
  1483.                         if (cmem0 == null)
  1484.                             cmem0 = cmem;
  1485.                         if (cons.return_type_expr != null)
  1486.                             cons.return_type_expr.context.HandleError(JSError.ConstructorMayNotHaveReturnType);
  1487.                         if ((cons.attributes & MethodAttributes.Abstract) != 0 || (cons.attributes & MethodAttributes.Static) != 0) {
  1488.                             cons.isStatic = false;
  1489.                             JSVariableField f = (JSVariableField)((JSFieldMethod)cmem).field;
  1490.                             f.attributeFlags &= ~FieldAttributes.Static;
  1491.                             f.originalContext.HandleError(JSError.NotValidForConstructor);
  1492.                         }
  1493.                         cons.return_type_expr = new TypeExpression(new ConstantWrapper(Typeob.Void, context));
  1494.                         cons.own_scope.AddReturnValueField();
  1495.                     }
  1496.                     //The else case can only happen if there is an error in the source code. Messages are generated elsewhere.
  1497.                 }
  1498.                 if (cmem0 != null)
  1499.                     this.classob.constructors = ((JSMemberField)((JSFieldMethod)cmem0).field).GetAsConstructors(this.classob);
  1500.                 else {
  1501.                     this.AllocateImplicitDefaultConstructor();
  1502.                     this.classob.constructors = new ConstructorInfo[] {new JSConstructor(this.implicitDefaultConstructor)};
  1503.                 }
  1504.             }
  1505.         }
  1506.        
  1507.         internal override void TranslateToIL(ILGenerator il, Type rtype)
  1508.         {
  1509.             this.GetTypeBuilderOrEnumBuilder();
  1510.             this.TranslateToCOMPlusClass();
  1511.             Debug.Assert(rtype == Typeob.Void);
  1512.             object tok = ((JSVariableField)this.ownField).GetMetaData();
  1513.             if (tok != null) {
  1514.                 //This case is here to make classes defined in the global scope accessible to eval
  1515.                 il.Emit(OpCodes.Ldtoken, this.classob.classwriter);
  1516.                 il.Emit(OpCodes.Call, CompilerGlobals.getTypeFromHandleMethod);
  1517.                 if (tok is LocalBuilder)
  1518.                     il.Emit(OpCodes.Stloc, (LocalBuilder)tok);
  1519.                 else
  1520.                     il.Emit(OpCodes.Stsfld, (FieldInfo)tok);
  1521.             }
  1522.         }
  1523.        
  1524.         internal override void TranslateToILInitializer(ILGenerator il)
  1525.         {
  1526.         }
  1527.        
  1528.         private void EmitUsingNamespaces(ILGenerator il)
  1529.         {
  1530.             if (this.body.Engine.GenerateDebugInfo) {
  1531.                 ScriptObject ns = this.enclosingScope;
  1532.                 while (ns != null) {
  1533.                     if (ns is PackageScope)
  1534.                         il.UsingNamespace(((PackageScope)ns).name);
  1535.                     else if (ns is WrappedNamespace && !((WrappedNamespace)ns).name.Equals(""))
  1536.                         il.UsingNamespace(((WrappedNamespace)ns).name);
  1537.                     ns = ns.GetParent();
  1538.                 }
  1539.             }
  1540.         }
  1541.        
  1542.         private void TranslateToCOMPlusClass()
  1543.         {
  1544.             if (this.isCooked)
  1545.                 return;
  1546.             this.isCooked = true;
  1547.             if (this is EnumDeclaration) {
  1548.                 if (!(this.enclosingScope is ClassScope))
  1549.                     this.TranslateToCreateTypeCall();
  1550.                 return;
  1551.             }
  1552.             if (this.superClass != null)
  1553.                 this.superClass.TranslateToCOMPlusClass();
  1554.             for (int i = 0int n = this.interfaces.Length; i < n; i++) {
  1555.                 IReflect iface = this.interfaces[i].ToIReflect();
  1556.                 if (iface is ClassScope)
  1557.                     ((ClassScope)iface).owner.TranslateToCOMPlusClass();
  1558.             }
  1559.            
  1560.             Globals.ScopeStack.Push(this.classob);
  1561.             TypeBuilder savedClasswriter = compilerGlobals.classwriter;
  1562.             compilerGlobals.classwriter = (TypeBuilder)this.classob.classwriter;
  1563.            
  1564.             if (!this.isInterface) {
  1565.                 //Emit the class initializer
  1566.                 ConstructorBuilder ccons = compilerGlobals.classwriter.DefineTypeInitializer();
  1567.                 ILGenerator il = ccons.GetILGenerator();
  1568.                 LocalBuilder engineLocal = null;
  1569.                 if (this.classob.staticInitializerUsesEval) {
  1570.                     engineLocal = il.DeclareLocal(Typeob.VsaEngine);
  1571.                     il.Emit(OpCodes.Ldtoken, this.classob.GetTypeBuilder());
  1572.                     ConstantWrapper.TranslateToILInt(il, 0);
  1573.                     il.Emit(OpCodes.Newarr, Typeob.JSLocalField);
  1574.                     if (this.Engine.PEFileKind == PEFileKinds.Dll) {
  1575.                         il.Emit(OpCodes.Ldtoken, this.classob.GetTypeBuilder());
  1576.                         il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngineWithType);
  1577.                     }
  1578.                     else
  1579.                         il.Emit(OpCodes.Call, CompilerGlobals.createVsaEngine);
  1580.                     il.Emit(OpCodes.Dup);
  1581.                     il.Emit(OpCodes.Stloc, engineLocal);
  1582.                     il.Emit(OpCodes.Call, CompilerGlobals.pushStackFrameForStaticMethod);
  1583.                     il.BeginExceptionBlock();
  1584.                 }
  1585.                 ((Block)(this.body)).TranslateToILStaticInitializers(il);
  1586.                 if (this.classob.staticInitializerUsesEval) {
  1587.                     il.BeginFinallyBlock();
  1588.                     il.Emit(OpCodes.Ldloc, engineLocal);
  1589.                     il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
  1590.                     il.Emit(OpCodes.Pop);
  1591.                     il.EndExceptionBlock();
  1592.                 }
  1593.                 il.Emit(OpCodes.Ret);
  1594.                
  1595.                 // Emit all the namespaces used by the class initializer
  1596.                 this.EmitUsingNamespaces(il);
  1597.                
  1598.                 //Emit the instance field initializer (this also emits the method bodies)
  1599.                 MethodBuilder initializer = compilerGlobals.classwriter.DefineMethod(".init", MethodAttributes.Private, Typeob.Void, new Type[0]);
  1600.                 this.fieldInitializer = initializer;
  1601.                 il = initializer.GetILGenerator();
  1602.                 if (this.classob.instanceInitializerUsesEval) {
  1603.                     il.Emit(OpCodes.Ldarg_0);
  1604.                     ConstantWrapper.TranslateToILInt(il, 0);
  1605.                     il.Emit(OpCodes.Newarr, Typeob.JSLocalField);
  1606.                     il.Emit(OpCodes.Ldarg_0);
  1607.                     il.Emit(OpCodes.Callvirt, CompilerGlobals.getEngineMethod);
  1608.                     il.Emit(OpCodes.Call, CompilerGlobals.pushStackFrameForMethod);
  1609.                     il.BeginExceptionBlock();
  1610.                 }
  1611.                 ((Block)(this.body)).TranslateToILInstanceInitializers(il);
  1612.                 if (this.classob.instanceInitializerUsesEval) {
  1613.                     il.BeginFinallyBlock();
  1614.                     il.Emit(OpCodes.Ldarg_0);
  1615.                     il.Emit(OpCodes.Callvirt, CompilerGlobals.getEngineMethod);
  1616.                     il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
  1617.                     il.Emit(OpCodes.Pop);
  1618.                     il.EndExceptionBlock();
  1619.                 }
  1620.                 il.Emit(OpCodes.Ret);
  1621.                
  1622.                 // Emit all the namespaces used by the instance initializer
  1623.                 this.EmitUsingNamespaces(il);
  1624.                
  1625.                 //Emit the default constructor
  1626.                 if (this.implicitDefaultConstructor != null)
  1627.                     this.implicitDefaultConstructor.TranslateToIL(compilerGlobals);
  1628.                
  1629.                 //Emit the expando code
  1630.                 if (this.generateCodeForExpando) {
  1631.                     this.GetExpandoIndexerGetter();
  1632.                     this.GetExpandoIndexerSetter();
  1633.                     this.GetExpandoDeleteMethod();
  1634.                     this.GenerateGetEnumerator();
  1635.                 }
  1636.                 this.EmitILForINeedEngineMethods();
  1637.             }
  1638.            
  1639.             if (!(this.enclosingScope is ClassScope))
  1640.                 this.TranslateToCreateTypeCall();
  1641.             compilerGlobals.classwriter = savedClasswriter;
  1642.             Globals.ScopeStack.Pop();
  1643.         }
  1644.        
  1645.         private void TranslateToCreateTypeCall()
  1646.         {
  1647.             if (this.cookedType != null)
  1648.                 return;
  1649.             if (this is EnumDeclaration) {
  1650.                 EnumBuilder eb = this.classob.classwriter as EnumBuilder;
  1651.                 if (eb != null)
  1652.                     this.cookedType = eb.CreateType();
  1653.                 else
  1654.                     this.cookedType = ((TypeBuilder)this.classob.classwriter).CreateType();
  1655.                 return;
  1656.             }
  1657.             if (this.superClass != null)
  1658.                 this.superClass.TranslateToCreateTypeCall();
  1659.             AppDomain currentDomain = System.Threading.Thread.GetDomain();
  1660.             ResolveEventHandler resolveHandler = new ResolveEventHandler(this.ResolveEnum);
  1661.             currentDomain.TypeResolve += resolveHandler;
  1662.             this.cookedType = ((TypeBuilder)this.classob.classwriter).CreateType();
  1663.             currentDomain.TypeResolve -= resolveHandler;
  1664.             foreach (JSMemberField field in this.fields) {
  1665.                 ClassScope csc = field.value as ClassScope;
  1666.                 if (csc == null)
  1667.                     continue;
  1668.                 csc.owner.TranslateToCreateTypeCall();
  1669.             }
  1670.         }
  1671.        
  1672.         private Assembly ResolveEnum(object sender, ResolveEventArgs args)
  1673.         {
  1674.             FieldInfo f = this.classob.GetField(args.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
  1675.             if (f != null && f.IsLiteral) {
  1676.                 ClassScope csc = TypeReferences.GetConstantValue(f) as ClassScope;
  1677.                 if (csc != null)
  1678.                     csc.owner.TranslateToCreateTypeCall();
  1679.             }
  1680.             return this.compilerGlobals.assemblyBuilder;
  1681.         }
  1682.        
  1683.         internal override Context GetFirstExecutableContext()
  1684.         {
  1685.             return null;
  1686.         }
  1687.     }
  1688. }

Developer Fusion