Пример #1
0
 public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure, CurrentClosure changes, CurrentClosure deletions, CurrentClosure insertions){
   this.UpdateSourceContext(currentClosure, changes);
   if (currentClosure == null) return changes;
   if (changes != null){
     if (deletions == null || insertions == null)
       Debug.Assert(false);
     else{
     }
   }else if (deletions != null)
     return null;
   return currentClosure;
 }
Пример #2
0
 public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure){
   return currentClosure;
 }
Пример #3
0
 public virtual Differences VisitCurrentClosure(CurrentClosure currentClosure1, CurrentClosure currentClosure2){
   Differences differences = new Differences(currentClosure1, currentClosure2);
   if (currentClosure1 == null || currentClosure2 == null){
     if (currentClosure1 != currentClosure2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++;
   }else{
     differences.NumberOfSimilarities++;
     differences.Changes = null;
   }
   return differences;
 }
Пример #4
0
    public override Expression VisitConstruct(Construct cons){
      if (cons == null) return cons;
      cons.Owner = this.VisitExpression(cons.Owner);
      cons.Constructor = this.VisitExpression(cons.Constructor);
      MemberBinding mb = cons.Constructor as MemberBinding;
      if (mb == null){
        Literal literal = cons.Constructor as Literal;
        if (literal == null) return cons;
        TypeNode t = literal.Value as TypeNode;
        if (t == null) return cons;
        cons.Type = t;
        cons.Constructor = mb = new MemberBinding(null, t);
        mb.SourceContext = literal.SourceContext;
      }else{
        TypeNode t = mb.BoundMember as TypeNode;
        if (t == null) return cons; //TODO: if the bound member is an instance initializer, use it.
        cons.Type = t;
      }
      AnonymousNestedFunction func = null;
      DelegateNode delType = cons.Type as DelegateNode;
      if (delType != null && cons.Operands != null && cons.Operands.Count == 1){
        Method meth = null;
        Expression ob = Literal.Null;
        Expression e = cons.Operands[0];
        MemberBinding emb = e as MemberBinding;
        if (emb != null) e = emb.BoundMemberExpression;
        TemplateInstance instance = e as TemplateInstance;
        TypeNodeList typeArguments = instance == null ? null : instance.TypeArguments;
        if (instance != null) e = instance.Expression;
        NameBinding nb = e as NameBinding;
        if (nb != null){
          meth = this.ChooseMethodMatchingDelegate(nb.BoundMembers, delType, typeArguments);
          if (meth != null && !meth.IsStatic)
            ob = new ImplicitThis();
          else if (meth == null){
            e = this.VisitExpression(e);
            if (e.Type is DelegateNode){
              meth = this.ChooseMethodMatchingDelegate(this.GetTypeView(e.Type).GetMembersNamed(StandardIds.Invoke), delType, typeArguments);
              if (meth != null)
                ob = e;
            }
          }
        }else{
          QualifiedIdentifier qualId = e as QualifiedIdentifier;
          if (qualId != null){
            ob = qualId.Qualifier = this.VisitExpression(qualId.Qualifier);
            if (ob is Literal && ob.Type == SystemTypes.Type)
              meth = this.ChooseMethodMatchingDelegate(this.GetTypeView((ob as Literal).Value as TypeNode).GetMembersNamed(qualId.Identifier), delType, typeArguments);
            else if (ob == null)
              return null;
            else if (ob != null && ob.Type != null){
              TypeNode oT = TypeNode.StripModifiers(ob.Type);
              Reference rT = oT as Reference;
              if (rT != null) oT = rT.ElementType;
              while (oT != null){
                meth = this.ChooseMethodMatchingDelegate(this.GetTypeView(oT).GetMembersNamed(qualId.Identifier), delType, typeArguments);
                if (meth != null) break;
                oT = oT.BaseType;
              }
            }
            if (meth == null){
              e = this.VisitExpression(e);
              if (e.Type is DelegateNode){
                meth = this.ChooseMethodMatchingDelegate(this.GetTypeView(e.Type).GetMembersNamed(StandardIds.Invoke), delType, typeArguments);
                if (meth != null){
                  qualId.BoundMember = new MemberBinding(e, meth, qualId.Identifier);
                  ob = e;
                }
              }
            }else
              qualId.BoundMember = new MemberBinding(ob, meth, qualId.Identifier);
          }else{
            func = e as AnonymousNestedFunction;
            if (func != null){
              meth = func.Method;
              if (meth != null){
                meth.ReturnType = delType.ReturnType;
                ParameterList mParams = meth.Parameters;
                ParameterList dParams = delType.Parameters;
                int n = mParams == null ? 0 : mParams.Count;
                int m = dParams == null ? 0 : dParams.Count;
                for (int i = 0; i < n; i++){
                  Parameter mPar = mParams[i];
                  if (mPar == null) return null;
                  if (i >= m){
                    if (mPar.Type == null) mPar.Type = SystemTypes.Object;
                    continue;
                  }
                  Parameter dPar = dParams[i];
                  if (mPar.Type == null){
                    if (dPar != null)
                      mPar.Type = dPar.Type;
                    if (mPar.Type == null)
                      mPar.Type = SystemTypes.Object;
                  }
                }
                if (n != m){
                  Node nde = new Expression(NodeType.Nop);
                  if (n == 0)
                    nde.SourceContext = cons.Constructor.SourceContext;
                  else{
                    nde.SourceContext = mParams[0].SourceContext;
                    nde.SourceContext.EndPos = mParams[n-1].SourceContext.EndPos;
                  }
                  this.HandleError(nde, Error.WrongNumberOfArgumentsForDelegate, this.GetTypeName(delType), n.ToString());
                  return null;
                }
                MemberList mems = meth.Scope == null ? null : meth.Scope.Members;
                n = mems == null ? 0 : mems.Count;
                for (int i = 0; i < n; i++){
                  ParameterField f = mems[i] as ParameterField;
                  if (f == null) continue;
                  Parameter p = f.Parameter;
                  if (p != null) f.Type = p.Type;
                }
                func = this.VisitAnonymousNestedFunction(func) as AnonymousNestedFunction;
                if (func == null) return null;
                meth = func.Method;
                if (meth == null || meth.DeclaringType == null) return null;
                ob = new CurrentClosure(meth, meth.DeclaringType);
              }
            }
          }
        }
        if (meth != null){
          Expression ldftn = null;
          MemberBinding memb = new MemberBinding(null, meth, e);
          memb.Type = null; //Signal to Checker not to complain about this reference to a method without parenthesis
          if (meth.IsVirtualAndNotDeclaredInStruct)
            ldftn = new BinaryExpression(new Expression(NodeType.Dup), memb, NodeType.Ldvirtftn);
          else{
            if (meth.IsStatic) ob = Literal.Null;
            ldftn = new UnaryExpression(memb, NodeType.Ldftn);
          }
          ldftn.Type = SystemTypes.IntPtr;
          ExpressionList arguments = cons.Operands = new ExpressionList(2);
          arguments.Add(ob);
          arguments.Add(ldftn);
          if (ob is ImplicitThis && this.currentMethod != null && this.currentMethod.IsStatic &&
            !(this.currentMethod.Scope.CapturedForClosure && meth.DeclaringType == this.currentMethod.Scope.ClosureClass)){
            this.HandleError(e, Error.ObjectRequired, this.GetMemberSignature(meth));
            return null;
          }
        }else{
          cons.Constructor = new Literal(delType);
          return cons;
        }
      }else{
        cons.Operands = this.VisitExpressionList(cons.Operands);
        UnaryExpression op2nd = cons.Operands != null && cons.Operands.Count > 1 ?
          cons.Operands[1] as UnaryExpression : null;
        if (op2nd != null){
          MemberBinding mb2nd = op2nd.Operand as MemberBinding;
          if (mb2nd != null && mb2nd.BoundMember is Method) mb2nd.Type = null;
        }
      }
      
      MemberList members = this.GetTypeView(cons.Type).GetConstructors();
      Method method = this.ResolveOverload(members, cons.Operands) as Method;
     
      if (method == null && cons.Operands != null && cons.Operands.Count == 1){
        Comprehension q = cons.Operands[0] as Comprehension;
        if (q == null) goto End;
        
        Method m2 = this.ResolveOverload(members, new ExpressionList()) as Method;
        //Method m2 = this.GetTypeView(cons.Type).GetConstructor(); // see if there is a nullary .ctor
        if (m2 == null && cons.Type.NodeType == NodeType.Class) goto End;
        TypeNode qType = TypeNode.StripModifiers(q.Type);
        if (q.Elements == null || qType== null || qType.TemplateArguments==null || qType.TemplateArguments.Count==0) goto End;

        if (this.GetTypeView(cons.Type).IsAssignableTo(SystemTypes.IList)){
          method = m2;
          q.AddMethod = SystemTypes.IList.GetMethod(StandardIds.Add,SystemTypes.Object);
        } else if ((q.Elements.Count == 0 || this.GetTypeView(qType.TemplateArguments[0]).IsAssignableTo(SystemTypes.DictionaryEntry)) && this.GetTypeView(cons.Type).IsAssignableTo(SystemTypes.IDictionary)) {
          method = m2;
          q.AddMethod = SystemTypes.IDictionary.GetMethod(StandardIds.Add,SystemTypes.Object,SystemTypes.Object);
        } else if (((q.Elements.Count == 0 || this.GetTypeView(qType.TemplateArguments[0]).IsAssignableTo(SystemTypes.DictionaryEntry)) && 
          (q.AddMethod = this.GetTypeView(cons.Type).GetMethod(StandardIds.Add,SystemTypes.Object, SystemTypes.Object)) != null) && 
          q.AddMethod.ReturnType == SystemTypes.Void){
          method = m2;
        } else if ((q.AddMethod = this.GetTypeView(cons.Type).GetMethod(StandardIds.Add,SystemTypes.Object)) != null &&
          q.AddMethod.ReturnType == SystemTypes.Int32){
          method = m2;
        } else
          q.AddMethod = null;

        // NB: if m2 is assigned to method, then the actual .ctor does *not* match the operands
        // but the Normalizer will compensate for it.
        // 2nd disjunct: don't need a .ctor method to construct a struct

        if ((method != null || cons.Type.NodeType == NodeType.Struct) && q.AddMethod!= null){
          // The Comprehension is going to replace the expression "new T{...}",
          // so it better have the same type
          // But Checker needs the T in the IEnumerable<T> that is sitting in q.Type, so
          // need a place to put it so Checker can find it. REVIEW!!!
          q.TemporaryHackToHoldType = q.Type;
          q.Type = cons.Type;
          if (method != null)
            q.nonEnumerableTypeCtor = method;
          else
            q.nonEnumerableTypeCtor = cons.Type;
          return q;
        }
      }
    End:
      
      if (method != null && method.DeclaringType == cons.Type){
        cons.Constructor = mb;
        mb.BoundMember = method;
      }
      if (cons != null) {
        Method m = method;
        if (m == null && members != null && members.Count > 0)
          m = members[0] as Method;
        if(m != null)
          this.ParameterPreselectionProcessing(m.Parameters, cons.Operands);
      }
      if (func != null){
        func.Invocation = cons;
        func.Type = cons.Type;
        return func;
      }
      if (cons.Type != null && !cons.Type.IsValueType && this.NonNullChecking)
        cons.Type = OptionalModifier.For(SystemTypes.NonNullType, cons.Type);
      return cons;
    }
Пример #5
0
    public override Expression VisitMethodCall(MethodCall call) {
      if (call == null) return null;
      NameBinding nb = call.Callee as NameBinding;
      if (nb != null) {      
        if (nb.Identifier != Looker.NotFound) {
          this.VisitNameBinding(nb); //Reports the error
          return null;
        }
        int numPars = call.Operands == null ? 0 : call.Operands.Count;
        bool callOperandsAlreadyNull = (call.Operands == null);
        ExpressionList operands = call.Operands = this.VisitExpressionList(call.Operands);
        if (operands == null && !callOperandsAlreadyNull || operands != null && operands.Count != numPars) return null;
        for (int i = 0; i < numPars; i++)
          if (call.Operands[i] == null) return null; //The error could have been caused by the bad argument.
        bool hasArglist = false;
        int arglistIndex = -1;

        for (int i = 0; i < numPars; i++) {
          if (call.Operands[i] is ArglistArgumentExpression) {
            hasArglist = true;
            arglistIndex = i;
            break;
          }
        }

        MemberList members = nb.BoundMembers;
        int n = members == null ? 0 : members.Count;
        MethodList ambiguousMethods = new MethodList(n);
        Method inaccessibleMethod = null;
        Method templateMethodWithFailedInference = null;
        Method objectMatchArglistMethod = null;
        for (int i = 0; i < n; i++) {
          Method meth = members[i] as Method;
          if (meth == null) continue;
          if ((meth.Parameters == null ? 0 : meth.Parameters.Count) != numPars) continue;
          if (this.NotAccessible(meth)) {
            inaccessibleMethod = meth;
            continue;
          } else {
            string mname = meth.Name != null ? meth.Name.ToString() :
        "";
            if (this.insideMethodContract  || this.insideInvariant) {
              if (!this.AsAccessible(meth, currentMethod) && !this.insideInvariant) {
                this.HandleError(meth, Error.MemberNotVisible, this.GetTypeName(meth.DeclaringType)+"."+mname); // WS better error message
                return null;
              }
              if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(meth, currentMethod)) {
                this.HandleError(meth, Error.MemberMustBePureForMethodContract, this.GetTypeName(meth.DeclaringType)+"."+mname);
                return null;
              }
              if (this.insideInvariant && !this.IsTransparentForInvariant(meth, currentMethod)) {
                this.HandleError(meth, Error.MemberMustBePureForInvariant, this.GetTypeName(meth.DeclaringType)+"."+mname);
                return null;
              }
            } else if (!this.IsModelUseOk(meth, currentMethod)) {
              this.HandleError(meth, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(meth.DeclaringType)+"."+mname);
              return null;
            }
          }
          if (meth.TemplateParameters != null && meth.TemplateParameters.Count > 0) {
            templateMethodWithFailedInference = meth;
            continue;
          }
          if (hasArglist && arglistIndex < meth.Parameters.Count && meth.Parameters[arglistIndex].Type == SystemTypes.Object) {
            objectMatchArglistMethod = meth;
          }
          ambiguousMethods.Add(meth);
        }
        if (ambiguousMethods.Count >= 2) {
          this.HandleError(call, Error.AmbiguousCall, this.GetMethodSignature(ambiguousMethods[0]), this.GetMethodSignature(ambiguousMethods[1]));
          return null;
        }
        if (inaccessibleMethod != null) {
          this.HandleError(call, Error.MemberNotVisible, this.GetMethodSignature(inaccessibleMethod));
          return null;
        }
        if (templateMethodWithFailedInference != null) {
          this.HandleError(call, Error.CannotInferMethTypeArgs, this.GetMethodSignature(templateMethodWithFailedInference));
          return null;
        }
        if (objectMatchArglistMethod != null) {
          this.HandleError(call, Error.CannotMatchArglist, objectMatchArglistMethod.Name.Name);
          this.HandleRelatedError(objectMatchArglistMethod);
          return null;
        }
        Identifier id = null;
        for (int i = 0; i < n; i++) {
          Member mem = members[i];
          if (!(mem is Method)) continue;
          if (id == null && mem.Name != null) {
            id = mem.Name;
            string name = id.Name;
            if (mem is InstanceInitializer && mem.DeclaringType != null && mem.DeclaringType.Name != null)
              name = mem.DeclaringType.Name.Name;
            else if (mem.IsSpecialName)
              name = this.GetMemberName(mem);
            this.HandleError(nb, Error.NoOverloadWithMatchingArgumentCount, name, (call.Operands == null ? 0 : call.Operands.Count).ToString());
          }
          this.HandleRelatedError(mem);
        }
        return null;
      }
      MemberBinding mb = call.Callee as MemberBinding;
      if (mb == null) {
        Expression e = this.VisitExpression(call.Callee);
        if (e != null) {
          if (e is Literal && e.Type == SystemTypes.Type)
            this.HandleError(e, Error.TypeInBadContext, this.GetTypeName((TypeNode)((Literal)e).Value));
          else {
            TemplateInstance templInst = e as TemplateInstance;
            if (templInst != null) {
              if (templInst.Expression == null || templInst.TypeArguments == null) return null;
              this.VisitExpression(templInst.Expression);
              return null;
            }
            //HS D
            if (call.Callee is Hole)
               return null;
            this.HandleError(e, Error.NoSuchMethod);
          }
        }
        return null;
      }
      Method method = mb.BoundMember as Method;
      if (method == null) {
        if (mb.BoundMember != null) {
          if (mb.BoundMember is Event)
            this.HandleError(mb, Error.BadCallToEventHandler, this.GetMemberSignature(mb.BoundMember));
          else
            this.HandleNonMethodWhereMethodExpectedError(mb, mb.BoundMember);
        }
        return null;
      }
      bool initialMayReferenceThisAndBase = this.MayReferenceThisAndBase;
      if (mb.TargetObject is ImplicitThis || mb.TargetObject is This || mb.TargetObject is Base) {
        if (method is InstanceInitializer) {
          this.MayReferenceThisAndBase = true;  //Base class constructor has been called
        } else if ((this.currentMethod == null && !this.insideModelfield // this is true when it is visited as part of a field initializer
                    || !this.MayReferenceThisAndBase) // this is true when it is visited as part of a ctor with an explicit call to base in the body
                   && !this.AllowThisTarget(method) && !this.insideInvariant) {
          if (mb.TargetObject is ImplicitThis) {
            this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method, true));
          } else if (mb.TargetObject is Base) {
            this.HandleError(mb.TargetObject, Error.BaseInBadContext);
          } else {
            this.HandleError(mb.TargetObject, Error.ThisInBadContext);
          }
          return null;
        }
      }
      if (method == Resolver.IndexerNotFound) {
        if (mb.TargetObject == null) return null;
        if (this.TypeInVariableContext(mb.TargetObject as Literal)) return null;
        Expression tgtObj = this.VisitExpression(mb.TargetObject);
        if (tgtObj == null) return null;
        this.HandleError(tgtObj, Error.NotIndexable, this.GetTypeName(mb.TargetObject.Type));
        return null;
      }
      if (method.Name == Looker.NotFound) {
        //TODO: report the error
        return null;
      }
      TypeNode obType = mb.TargetObject == null ? null : mb.TargetObject.Type;
      if (mb.TargetObject is Base) obType = this.currentType;
      obType = TypeNode.StripModifiers(obType);
      if (this.NotAccessible(method, ref obType)) {
        if (method.IsSpecialName && method.Parameters != null && method.Parameters.Count > 0 && method.Name.ToString().StartsWith("get_"))
          this.HandleError(call, Error.NotIndexable, this.GetTypeName(mb.TargetObject.Type));
        else if (mb.TargetObject == null || mb.TargetObject.Type == null || this.NotAccessible(method))
          this.HandleError(call, Error.MemberNotVisible, this.GetMethodSignature(method));
        else
          this.HandleError(mb.BoundMemberExpression == null ? mb : mb.BoundMemberExpression, Error.NotVisibleViaBaseType, this.GetMethodSignature(method),
            this.GetTypeName(mb.TargetObject.Type), this.GetTypeName(this.currentType));
        return null;
      } else {
        if (this.insideMethodContract || this.insideInvariant || this.insideAssertOrAssume) {
          string mname = method.Name == null ? "" : method.Name.ToString();
          if (!this.AsAccessible(method, currentMethod) && !this.insideInvariant && !this.insideMethodContract && !this.insideAssertOrAssume) {
            this.HandleError(mb, Error.MemberNotVisible, this.GetTypeName(method.DeclaringType)+"."+mname);
            return null;
          }
          if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(method, currentMethod)) {
            this.HandleError(mb, Error.MemberMustBePureForMethodContract, this.GetTypeName(method.DeclaringType)+"."+mname);
            return null;
          }
          if (this.insideInvariant && !this.IsTransparentForInvariant(method, currentMethod)) {
            this.HandleError(mb, Error.MemberMustBePureForInvariant, this.GetTypeName(method.DeclaringType)+"."+mname);
            return null;
          }
        } else if (!this.IsModelUseOk(method, currentMethod)) {
          string mname = method.Name == null ? "" : method.Name.ToString();
          this.HandleError(mb, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(method.DeclaringType)+"."+mname);
          return null;
        }
      }
      this.CheckDirectCallOfFinalize(method, call);
      if (method == this.currentMethod && method is InstanceInitializer)
      {
        this.HandleError(call, Error.RecursiveConstructorCall, this.GetMethodSignature(method));
        return null;
      }
      if (method.IsStatic) {
        Expression targetOb = mb.TargetObject;
        if (targetOb != null) {
          MemberBinding memb = targetOb as MemberBinding;
          if (memb == null || memb.BoundMember == null || memb.Type == null || memb.Type.Name == null ||
            memb.BoundMember.Name.UniqueIdKey != memb.Type.Name.UniqueIdKey) {
            MethodCall mcall = targetOb as MethodCall;
            memb = mcall == null ? null : mcall.Callee as MemberBinding;
            TypeNode mcallType = mcall == null ? null : TypeNode.StripModifiers(mcall.Type);
            if (memb == null || memb.BoundMember == null || !memb.BoundMember.IsSpecialName || mcallType == null ||
              mcallType.Name == null || memb.BoundMember.Name.ToString() != "get_"+mcallType.Name.ToString()) {
              targetOb = this.VisitExpression(targetOb);
              if (targetOb != null)
                this.HandleError(targetOb, Error.TypeNameRequired, this.GetMethodSignature(method));
            }
          }
          mb.TargetObject = targetOb = null;
        }
      } else {
        bool targetObIsNonNull = false;
        bool outerMayReferenceThisAndBase = this.MayReferenceThisAndBase;
        if (this.AllowThisTarget(method)) this.MayReferenceThisAndBase = true;
        Expression targetOb = mb.TargetObject = this.VisitExpression(mb.TargetObject);
        this.MayReferenceThisAndBase = outerMayReferenceThisAndBase;
        if (targetOb != null)
          targetObIsNonNull = this.typeSystem.IsNonNullType(targetOb.Type);
        if (targetOb is Literal && targetOb.Type == SystemTypes.Type) {
          this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method, true));
          return null;
        }
        if (this.currentMethod != null && this.currentMethod.IsStatic) {
          if (targetOb is ImplicitThis || targetOb is This || targetOb is Base) {
            ImplicitThis ithis = targetOb as ImplicitThis;
            if (ithis != null) {
              bool callToNestedFunction = false;
              if (this.currentMethod.Scope.CapturedForClosure) {
                TypeNode t = this.currentMethod.Scope.ClosureClass;
                while (t != null && !callToNestedFunction) {
                  callToNestedFunction = t == method.DeclaringType;
                  t = t.BaseType;
                }
              }
              if (!callToNestedFunction) ithis = null;
            }
            if (ithis == null) {
              this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method));
              return null;
            }
            targetOb = new CurrentClosure(this.currentMethod, this.currentMethod.DeclaringType);
          }
        }
        TypeNode tObType = method.DeclaringType;
        if (tObType == null) return null;
        if (tObType.TemplateParameters != null && tObType.Template == null)
          tObType = tObType.GetTemplateInstance(tObType, tObType.TemplateParameters);
        if ((method.CallingConvention & CallingConventionFlags.ExplicitThis) != 0) {
          if (method.Parameters == null || method.Parameters.Count < 1 || method.Parameters[0] == null)
            Debug.Assert(false);
          else
            tObType = method.Parameters[0].Type;
        }
        if (tObType != null) {
          if (targetOb == null) return null;
          if (tObType.IsValueType) {
            targetOb = this.ConvertValueTypeCallTarget(targetOb, method, tObType);
            if (targetOb == null) return null;
            mb.TargetObject = this.GetAddressOf(targetOb, tObType);
          } else if (targetOb is Base && this.currentType != null && this.currentType.IsValueType) {
            targetOb = new AddressDereference(targetOb, this.currentType);
            mb.TargetObject = new BinaryExpression(targetOb, new MemberBinding(null, this.currentType), NodeType.Box, tObType);
          } else {
            if (tObType != targetOb.Type && !(targetOb is CurrentClosure && tObType is ClosureClass) && !(targetOb is This || targetOb is ImplicitThis)) {
              if (this.useGenerics && targetOb.Type is ITypeParameter && method.IsVirtual) {
                call.Constraint = targetOb.Type;
                if (targetOb.NodeType == NodeType.Indexer)
                  targetOb = mb.TargetObject = new UnaryExpression(targetOb, NodeType.ReadOnlyAddressOf, targetOb.Type.GetReferenceType());
                else
                  targetOb = mb.TargetObject = this.GetAddressOf(targetOb, targetOb.Type);
              } else {
                Reference refType = targetOb.Type as Reference;
                if (this.useGenerics && refType != null && refType.ElementType is ITypeParameter)
                  call.Constraint = refType.ElementType;
                else
                  targetOb = mb.TargetObject = this.typeSystem.ExplicitCoercion(targetOb, tObType, this.TypeViewer);
              }
              if (targetOb == null) return null;
            } else if (targetOb.Type != null && !this.GetTypeView(targetOb.Type).IsAssignableTo(tObType) && targetOb.Type.IsNestedIn(tObType)) {
              this.HandleError(mb, Error.AccessToNonStaticOuterMember, this.GetTypeName(tObType), this.GetTypeName(targetOb.Type));
              return null;
            }
          }
        }
      }
      bool savedMayReferenceThisAndBase = this.MayReferenceThisAndBase;
      this.MayReferenceThisAndBase = initialMayReferenceThisAndBase;
      this.CoerceArguments(method.Parameters, ref call.Operands, this.DoNotVisitArguments(method), method.CallingConvention);
      this.MayReferenceThisAndBase = savedMayReferenceThisAndBase;
      this.CheckForObsolesence(call, method);
      if (call.GiveErrorIfSpecialNameMethod && method.IsSpecialName) {
        string mname = method.Name == null ? null : method.Name.Name;
        if (mname != null && (mname.StartsWith(".") || mname.StartsWith("get_") || mname.StartsWith("set_") || mname.StartsWith("add_") || mname.StartsWith("remove_")))
          this.HandleError(call, Error.CannotCallSpecialMethod, this.GetMethodSignature(method));
      }
      if (method.IsAbstract && call.NodeType != NodeType.Callvirt) {
        Debug.Assert(mb.TargetObject is Base);
        this.HandleError(call, Error.AbstractBaseCall, this.GetMethodSignature(method));
      }
      if (mb != null) {
        if (method != null && method.Contract != null && method.Contract.Ensures != null) {
          // Look at any checked exceptions listed in m's contract and make sure they
          // are covered by the list of allowedExceptions
          for (int i = 0, n = method.Contract.Ensures.Count; i < n; i++) {
            EnsuresExceptional ee = method.Contract.Ensures[i] as EnsuresExceptional;
            if (ee == null)
              continue;
            TypeNode thrownType = ee.Type;
            if (thrownType == null) continue;
            if (!this.GetTypeView(thrownType).IsAssignableTo(SystemTypes.ICheckedException))
              continue;
            int j = 0;
            int p = this.allowedExceptions.Count;
            while (j < p) {
              TypeNode t = this.allowedExceptions[j];
              if (this.GetTypeView(thrownType).IsAssignableTo(t))
                break;
              j++;
            }
            if (j == p) { // no allowed exception covers this one
              this.HandleError(call, Error.CheckedExceptionNotInThrowsClause, this.GetTypeName(thrownType), this.GetMethodSignature(this.currentMethod));
            }
          }
        }
      }
      int numTemplArgs = method.TemplateArguments == null ? 0 : method.TemplateArguments.Count;
      if (method != null && numTemplArgs > 0) {
        // check instantiation constraints
        int len = method.Template.TemplateParameters == null ? 0 : method.Template.TemplateParameters.Count;
        if (numTemplArgs != len) {
          this.HandleError(call, Error.TemplateTypeRequiresArgs, this.GetMethodSignature(method.Template), len.ToString(), "method");
          return call;
        }
        Specializer specializer = len == 0 ? null : new Specializer(method.DeclaringType.DeclaringModule, method.Template.TemplateParameters, method.TemplateArguments);
        if (specializer != null) specializer.CurrentType = this.currentType;
        for (int i=0; i < len; i++) {
          TypeNode formal = method.Template.TemplateParameters[i];
          ITypeParameter formaltp = (ITypeParameter)formal;
          TypeNode actual = method.TemplateArguments[i];
          if (formal == null || actual == null) continue;
          // make sure actual is assignable to base of formal and to each interface
          TypeNode fbaseType = specializer == null ? formal.BaseType : specializer.VisitTypeReference(formal.BaseType);
          if (fbaseType != null && (
                ((formaltp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) == TypeParameterFlags.ReferenceTypeConstraint && !actual.IsObjectReferenceType)
                || ((formaltp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) == TypeParameterFlags.ValueTypeConstraint && !actual.IsValueType)
                || !this.typeSystem.AssignmentCompatible(TypeNode.StripModifiers(actual), fbaseType, this.TypeViewer))) {
            Node offNode = call.CalleeExpression is TemplateInstance ? (Node)((TemplateInstance)call.CalleeExpression).TypeArgumentExpressions[i] : (Node)call.CalleeExpression;
            this.HandleError(offNode,
              Error.TypeParameterNotCompatibleWithConstraint, this.GetTypeName(actual),
              this.GetTypeName(fbaseType),
              this.GetTypeName(formal),
              this.GetMethodSignature(method.Template));
            return call;
          }
          InterfaceList formal_ifaces = this.GetTypeView(formal).Interfaces;
          if (formal_ifaces != null) {
            for (int j = 0, n = formal_ifaces.Count; j < n; j++) {
              TypeNode intf = specializer == null ? formal_ifaces[j] : specializer.VisitTypeReference(formal_ifaces[j]);
              intf = TypeNode.StripModifiers(intf);
              if (intf == null) continue;
              if (intf != SystemTypes.ITemplateParameter && !this.typeSystem.AssignmentCompatible(TypeNode.StripModifiers(actual), intf, this.TypeViewer)) {
                Node offNode = call.CalleeExpression is TemplateInstance ? (Node)((TemplateInstance)call.CalleeExpression).TypeArgumentExpressions[i] : (Node)call.CalleeExpression;
                this.HandleError(offNode,
                  Error.TypeParameterNotCompatibleWithConstraint, this.GetTypeName(actual),
                  this.GetTypeName(intf),
                  this.GetTypeName(formal),
                  this.GetMethodSignature(method.Template));
                return call;
              }
            }
          }
        }
        this.CheckGenericMethodSpecialConstraints(method, call);
      }

      return call;
    }
Пример #6
0
 public virtual void VisitCurrentClosure(CurrentClosure currentClosure)
 {
 }
Пример #7
0
 public override Expression VisitCurrentClosure(CurrentClosure currentClosure)
 {
     if (currentClosure == null) return null;
     return base.VisitCurrentClosure((CurrentClosure)currentClosure.Clone());
 }
Пример #8
0
 public override Expression VisitCurrentClosure(CurrentClosure currentClosure){
   if (currentClosure == null) return null;
   if (this.currentClosureLocal == null && this.currentThisParameter != null) 
     return new ThisBinding(this.currentThisParameter, currentClosure.SourceContext);
   return this.currentClosureLocal;
 }
Пример #9
0
 public virtual void EndCurrentClosure(CurrentClosure cc) {
   if (cc != null){
     //TODO: factor out the code for constructing the closure class, so that this elaborate setup is not necessary
     Checker checker = new Checker(null, this.typeSystem, null, null, null);
     checker.currentType = this.typeSystem.currentType = this.currentType;
     checker.currentMethod = this.currentMethod;
     Block oldBody = cc.Method.Body;
     TypeNode yieldType = this.typeSystem.GetStreamElementType(cc.Type, this.TypeViewer);
     cc.Method.Body = new Block(new StatementList(new Yield(new Literal(null, yieldType))));
     checker.VisitMethod(cc.Method);
     Return ret = cc.Method.Body.Statements[0] as Return;
     Debug.Assert(ret != null);
     if (ret != null) {
       ConstructIterator ci = ret.Expression as ConstructIterator;
       Debug.Assert(ci != null);
       if (ci != null) {
         ci.Body = oldBody;
         cc.Method.Body.Scope = oldBody.Scope;
         this.VisitMethod(cc.Method);
       }
     }
   }
 }
Пример #10
0
 public virtual CurrentClosure BeginCurrentClosure(TypeNode yieldType, string name) {
   TypeNode returnType = SystemTypes.GenericIEnumerable.GetTemplateInstance(this.currentType, new TypeNodeList(yieldType));
   Class closureClass = this.currentMethod.Scope.ClosureClassTemplateInstance;
   Method method = new Method();
   method.Name = Identifier.For(name + ":" + method.UniqueKey);
   method.Flags = MethodFlags.CompilerControlled|MethodFlags.Assembly;
   method.CallingConvention = CallingConventionFlags.HasThis;
   method.InitLocals = true;
   method.DeclaringType = closureClass;
   method.Body = new Block(new StatementList());
   method.Scope = new MethodScope(this.currentMethod.Scope, null, method);
   method.Body.Scope = new BlockScope(method.Scope, method.Body);
   method.ReturnType = returnType;
   closureClass.Members.Add(method);
   CurrentClosure cc = new CurrentClosure(method, returnType);
   return cc;
 }