Microsoft.JScript.FunctionObject.PartiallyEvaluate C# (CSharp) Method

PartiallyEvaluate() private method

private PartiallyEvaluate ( ) : void
return void
      internal void PartiallyEvaluate(){
        if (this.partiallyEvaluated)
          return;
        
        // 49885 - Putting class definitions in a package makes class order dependent
        // For methods, the logic in FunctionObject.PartiallyEvaluate must be called by
        // Class.PartiallyEvaluate in order to ensure that the scope chain is set up correctly.
        ClassScope classScope = this.enclosing_scope as ClassScope;
        if (null != classScope)
          classScope.owner.PartiallyEvaluate();

        // In the case where the the caller is Class.PartiallyEvaluate, the call returns
        // immediately since Class.partiallyEvaluated wil be set and this.partiallEvaluated
        // will still be false to allow the partial evaluation to be computed. In the case where 
        // the caller isn't Class.PartiallyEvaluate, the call to Class.PartiallyEvaluate results
        // in a call back to FunctionObject.PartiallyEvaluate. This call will set this.partiallyEvaluated
        // and thus, we will not need to evaluate again.
        if (this.partiallyEvaluated)
          return;
        
          
        this.partiallyEvaluated = true;
        // deal with custom attributes
        this.clsCompliance = CLSComplianceSpec.NotAttributed;
        if (this.customAttributes != null){
          this.customAttributes.PartiallyEvaluate();
          CustomAttribute clsAttr = this.customAttributes.GetAttribute(Typeob.CLSCompliantAttribute);
          if (clsAttr != null){
            this.clsCompliance = clsAttr.GetCLSComplianceValue();
            this.customAttributes.Remove(clsAttr);
          }
          clsAttr = this.customAttributes.GetAttribute(Typeob.Override);
          if (clsAttr != null){
            if (this.isStatic)
              clsAttr.context.HandleError(JSError.StaticMethodsCannotOverride);
            else
              this.attributes &= ~MethodAttributes.NewSlot;
            this.noVersionSafeAttributeSpecified = false;
            this.customAttributes.Remove(clsAttr);
          }
          clsAttr = this.customAttributes.GetAttribute(Typeob.Hide);
          if (clsAttr != null){
            if (!this.noVersionSafeAttributeSpecified){
              clsAttr.context.HandleError(JSError.OverrideAndHideUsedTogether);
              this.attributes |= MethodAttributes.NewSlot;
              this.noVersionSafeAttributeSpecified = true;
            }else{
              if (this.isStatic)
                clsAttr.context.HandleError(JSError.StaticMethodsCannotHide);
              this.noVersionSafeAttributeSpecified = false;
            }
            this.customAttributes.Remove(clsAttr);
          }
          CustomAttribute expAttr = this.customAttributes.GetAttribute(Typeob.Expando);
          if (expAttr != null){
            if (!this.noVersionSafeAttributeSpecified && (this.attributes & MethodAttributes.NewSlot) == 0){
              expAttr.context.HandleError(JSError.ExpandoPrecludesOverride);
              this.attributes |= MethodAttributes.NewSlot;
              this.noVersionSafeAttributeSpecified = true;
            }
            if (this.isConstructor)
              expAttr.context.HandleError(JSError.NotValidForConstructor);
            else if ((this.attributes & MethodAttributes.Abstract) != 0)
              expAttr.context.HandleError(JSError.ExpandoPrecludesAbstract);
            else if ((this.attributes & MethodAttributes.Static) != 0)
              expAttr.context.HandleError(JSError.ExpandoPrecludesStatic);
            else if ((this.attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public)
              expAttr.context.HandleError(JSError.ExpandoMustBePublic);
            else{
              this.own_scope.isMethod = false;
              this.isMethod = false;
              this.isExpandoMethod = true;
              this.isStatic = true;
              this.attributes &= ~MethodAttributes.Virtual;
              this.attributes &= ~MethodAttributes.NewSlot;
              this.attributes |= MethodAttributes.Static;
            }
          }
        }
        for (int i = 0, n = this.parameter_declarations.Length; i < n; i++){
          this.parameter_declarations[i].PartiallyEvaluate();
          JSLocalField pfield = (JSLocalField)this.own_scope.name_table[this.formal_parameters[i]];
          pfield.type = this.parameter_declarations[i].type;
          if (pfield.type == null)
            pfield.type = new TypeExpression(new ConstantWrapper(Typeob.Object, this.parameter_declarations[i].context));
          pfield.isDefined = true;
        }
        if (this.return_type_expr != null){
          this.return_type_expr.PartiallyEvaluate();
          this.own_scope.returnVar.type = this.return_type_expr;
          if (this.own_scope.returnVar.type.ToIReflect() == Typeob.Void){
            this.own_scope.returnVar.type = null;
            this.own_scope.returnVar = null; //This does not completely get rid of the returnVar value, but acts as flag, hence the above.
          }
        }
        globals.ScopeStack.Push(this.own_scope);
        if (!this.own_scope.isKnownAtCompileTime) //Function contains an eval. Type inference is impossible for local vars
          for (int i = 0, n = this.fields.Length; i < n; i++)
            this.fields[i].SetInferredType(Typeob.Object, null);
        if (!this.isConstructor)
          this.body.PartiallyEvaluate();
        else{
          this.body.MarkSuperOKIfIsFirstStatement();
          this.body.PartiallyEvaluate(); //super constructor calls that have not been marked OK will generate errors
          ClassScope cscope = (ClassScope)this.enclosing_scope;
          int n = this.superConstructorCall == null ? 0 : this.superConstructorCall.arguments.count;
          Type[] argTypes = n == 0 ? Type.EmptyTypes : new Type[n];
          IReflect[] argIRs = new IReflect[n];
          for (int i = 0; i < n; i++)
            argIRs[i] = this.superConstructorCall.arguments[i].InferType(null);
          Context errorContext = this.superConstructorCall == null ? this.funcContext : this.superConstructorCall.context;
          try{
            if (this.superConstructorCall != null && !this.superConstructorCall.isSuperConstructorCall)
              this.superConstructor = JSBinder.SelectConstructor(cscope.constructors, argIRs);
            else
              this.superConstructor = cscope.owner.GetSuperConstructor(argIRs);
            if (this.superConstructor == null)
              errorContext.HandleError(JSError.SuperClassConstructorNotAccessible);
            else{
              ConstructorInfo cons = (ConstructorInfo)this.superConstructor;
              if (!cons.IsPublic && !cons.IsFamily && !cons.IsFamilyOrAssembly &&
                !(this.superConstructor is JSConstructor && ((JSConstructor)this.superConstructor).IsAccessibleFrom(this.enclosing_scope))){
                errorContext.HandleError(JSError.SuperClassConstructorNotAccessible);
                  this.superConstructor = null;
              }else if (n > 0)
                if (!Binding.CheckParameters(cons.GetParameters(), argIRs, this.superConstructorCall.arguments, this.superConstructorCall.context))
                  this.superConstructor = null;
            }
          }catch(AmbiguousMatchException){
            errorContext.HandleError(JSError.AmbiguousConstructorCall);
          }  
        }
        this.own_scope.HandleUnitializedVariables();
        globals.ScopeStack.Pop();
        this.must_save_stack_locals = this.own_scope.mustSaveStackLocals;
        this.fields = this.own_scope.GetLocalFields();
      }