public override Expression VisitMemberBinding(MemberBinding memberBinding){
   if (memberBinding == null) return null;
   if (memberBinding.BoundMember != null){
     if (!memberBinding.BoundMember.IsStatic){
       //add precondition that target object is not null
     }
   }
   return base.VisitMemberBinding(memberBinding);
 }
Example #2
0
 public override Expression VisitRefTypeExpression(RefTypeExpression reftypexp) {
   if (reftypexp == null) return null;
   Expression result = base.VisitRefTypeExpression (reftypexp);
   if (result != reftypexp) return result;
   UnaryExpression refanytype = new UnaryExpression(reftypexp.Operand, NodeType.Refanytype, SystemTypes.RuntimeTypeHandle, reftypexp.SourceContext);
   ExpressionList arguments = new ExpressionList(1);
   arguments.Add(refanytype);
   MemberBinding mb = new MemberBinding(null, Runtime.GetTypeFromHandle);
   return new MethodCall(mb, arguments, NodeType.Call, SystemTypes.Type);
 }
 internal override MemberBinding AsBinding() {
     switch (_action) {
         case RewriteAction.None:
             return _binding;
         case RewriteAction.Copy:
             MemberBinding[] newBindings = new MemberBinding[_bindings.Count];
             for (int i = 0; i < _bindings.Count; i++) {
                 newBindings[i] = _bindingRewriters[i].AsBinding();
             }
             return Expression.MemberBind(_binding.Member, new TrueReadOnlyCollection<MemberBinding>(newBindings));
     }
     throw ContractUtils.Unreachable;
 }
        public override void VisitMemberBinding(MemberBinding memberBinding)
        {
            var method = memberBinding.BoundMember as Method;
            if (method != null)
            {
                string message;
                if (_problematicTypes.TryGetValue(method.DeclaringType.FullName, out message))
                {
                    Problems.Add(new Problem(GetResolution(method.DeclaringType.FullName, message), memberBinding.UniqueKey.ToString()));
                }
            }

            base.VisitMemberBinding(memberBinding);
        }
 internal static BindingRewriter Create(MemberBinding binding, StackSpiller spiller, Stack stack) {
     switch (binding.BindingType) {
         case MemberBindingType.Assignment:
             MemberAssignment assign = (MemberAssignment)binding;
             return new MemberAssignmentRewriter(assign, spiller, stack);
         case MemberBindingType.ListBinding:
             MemberListBinding list = (MemberListBinding)binding;
             return new ListBindingRewriter(list, spiller, stack);
         case MemberBindingType.MemberBinding:
             MemberMemberBinding member = (MemberMemberBinding)binding;
             return new MemberMemberBindingRewriter(member, spiller, stack);
     }
     throw Error.UnhandledBinding();
 }
 public override Expression VisitMemberBinding(MemberBinding binding) 
 {
   Member boundMember = binding.BoundMember;
   if (boundMember is Field && !boundMember.IsStatic && boundMember.DeclaringType != null && boundMember.DeclaringType.Contract != null && boundMember.DeclaringType.Contract.FramePropertyGetter != null && boundMember != boundMember.DeclaringType.Contract.FrameField) 
   {
     Expression target = VisitExpression(binding.TargetObject);
     // Since we do not visit member bindings of assignment statements, we know/guess that this is a ldfld.
     Local targetLocal = new Local(boundMember.DeclaringType);
     Statement evaluateTarget = new AssignmentStatement(targetLocal, target, binding.SourceContext);
     Expression guard = new MethodCall(new MemberBinding(targetLocal, boundMember.DeclaringType.Contract.FramePropertyGetter), null, NodeType.Call, SystemTypes.Guard);
     Statement check = new ExpressionStatement(new MethodCall(new MemberBinding(guard, SystemTypes.Guard.GetMethod(Identifier.For("CheckIsReading"))), null, NodeType.Call, SystemTypes.Void));
     Statement ldfld = new ExpressionStatement(new MemberBinding(targetLocal, boundMember, binding.SourceContext));
     return new BlockExpression(new Block(new StatementList(new Statement[] {evaluateTarget, check, ldfld})), binding.Type);
   }
   else
   {
     return base.VisitMemberBinding(binding);
   }
 }
 public override Expression VisitMemberBinding(MemberBinding memberBinding){
   if (memberBinding == null) return null;
   Field f = memberBinding.BoundMember as Field;
   if (f != null){
     if (f.IsLiteral){
       if (f.DefaultValue != null) return f.DefaultValue;
       Expression e = f.Initializer;
       if (e == Evaluator.BeingEvaluated) throw new CircularConstantException();
       f.Initializer = Evaluator.BeingEvaluated;
       Literal lit = null;
       try{
         lit = this.VisitExpression(e) as Literal;
       }catch(CircularConstantException){
         f.Initializer = null;
         throw;
       }
       if (lit != null){
         if (f.DeclaringType is EnumNode && f.Type == f.DeclaringType) lit.Type = f.DeclaringType;
         f.DefaultValue = lit;
         f.Initializer = null;
         return lit;
       }
     }else{
       //Should never get here from the compiler itself, but only from runtime code paths.
       if (f.IsStatic) return f.GetValue(null);
       Expression targetLiteral = this.VisitExpression(memberBinding.TargetObject) as Expression;
       if (targetLiteral != null){
         // HACK: Unary Expressions with NodeType "AddressOf" not getting converted to Literal.
         UnaryExpression uexpr = targetLiteral as UnaryExpression;
         if (uexpr != null)
           targetLiteral = this.VisitExpression(uexpr.Operand);
         if (targetLiteral is Literal)
           return f.GetValue(targetLiteral as Literal);
       }
     }
   }
   return null;
 }
 internal BindingRewriter(MemberBinding binding, StackSpiller spiller)
 {
     _binding = binding;
     _spiller = spiller;
 }
Example #9
0
 //This class could be extended to allow more expressions as a witness
 //Throws ApplicationException if expression not admissible.
   public override Expression VisitMemberBinding(MemberBinding memberBinding) {
     if (memberBinding.BoundMember == null || memberBinding.BoundMember.DeclaringType is BlockScope)
       throw new ApplicationException("unimplemented"); //DeclaringType is BlockScope indicates a local variable 
     return memberBinding;
   }
Example #10
0
 public virtual void SerializeContracts(TypeNode type) {
   Debug.Assert(type != null);
   if (type.Contract != null && this.currentOptions != null && !this.currentOptions.DisableInternalContractsMetadata) {
     TypeContract contract = type.Contract;
     #region serialize invariants
     for (int i = 0, n = contract.Invariants == null ? 0 : contract.Invariants.Count; i < n; i++) {
       Invariant inv = contract.Invariants[i];
       if (inv == null) continue;
       ExpressionList el = SplitConjuncts(inv.Condition);
       for (int j = 0, m = el.Count; j < m; j++) {
         InstanceInitializer ctor = SystemTypes.InvariantAttribute.GetConstructor(SystemTypes.String);
         AttributeNode a = Checker.SerializeExpression(ctor, el[j], this.currentModule);
         type.Attributes.Add(a);
       }
     }
     #endregion
     #region if type is a class, then serialize its modelfieldcontracts
     foreach (ModelfieldContract mfC in contract.ModelfieldContracts) {
       if (!(type is Class)) break;          
       #region Adorn type with ModelfieldContractAttribute containing serialized modelfield and witness of mfC
       Debug.Assert(mfC != null);  //something's wrong in the code.
       if (mfC.Witness == null) continue; //something's wrong in the input ssc (but should already have dealt with)  
       MemberBinding thisMf = new MemberBinding(new This(mfC.Modelfield.DeclaringType), mfC.Modelfield);
       InstanceInitializer wCtor = SystemTypes.ModelfieldContractAttribute.GetConstructor(SystemTypes.String, SystemTypes.String);
       AttributeNode a = Checker.SerializeExpressions(wCtor, new ExpressionList(thisMf, mfC.Witness), mfC.Witness.SourceContext, this.currentModule);
       type.Attributes.Add(a);
       #endregion
       #region For each satisfies clause of mfC, adorn type with SatisfiesAttributes containing serialized field + clauseConjunct
       foreach (Expression satClause in mfC.SatisfiesList) {
         if (satClause == null) continue; //don't report error, has already been done.
         foreach (Expression satConjunct in SplitConjuncts(satClause)) { //storing the conjuncts individually allows better error reporting 
           InstanceInitializer ctor = SystemTypes.SatisfiesAttribute.GetConstructor(SystemTypes.String, SystemTypes.String);
           AttributeNode attr = Checker.SerializeExpressions(ctor, new ExpressionList(thisMf, satConjunct), satConjunct.SourceContext, this.currentModule);
           type.Attributes.Add(attr);
         }
       }
       #endregion
     }
     #endregion
   }
   foreach (Member m in type.Members) {
     if ((m is Field && (m as Field).IsModelfield) || (m is Property && (m as Property).IsModelfield)) {
       #region Slap on ModelfieldAttribute
       InstanceInitializer mfCtor = SystemTypes.ModelfieldAttribute.GetConstructor();
       MemberBinding attrBinding = new MemberBinding(null, mfCtor);
       m.Attributes.Add(new AttributeNode(attrBinding, null));
       #endregion
     }
     Method meth = m as Method;        
     if (meth != null && meth.Contract != null) {
       if (meth.IsVisibleOutsideAssembly ? !(this.currentOptions != null && this.currentOptions.DisablePublicContractsMetadata) : !(this.currentOptions != null && this.currentOptions.DisableInternalContractsMetadata))
         this.SerializeMethodContract(meth.Contract);
     }        
   }
 }
Example #11
0
 public virtual Expression VisitMemberBinding(MemberBinding memberBinding, bool isTargetOfAssignment) {
   if (memberBinding == null) return null;
   Member mem = memberBinding.BoundMember;
   if (mem == null) return null;
   TypeNode memType = mem.DeclaringType;
   Expression originalTarget = memberBinding.TargetObject;
   Expression target = originalTarget;
   if (mem.IsStatic) {
     this.VisitTypeReference(mem.DeclaringType);
   }
   if (target != null) {
     QueryContext qc = target as QueryContext;
     if (qc != null && qc.Type == null) {
       this.HandleError(memberBinding, Error.IdentifierNotFound, mem.Name.ToString());
       return null;
     }
     target = memberBinding.TargetObject = this.VisitExpression(target);
     if (target == null) return null;
   }
   Property prop = mem as Property;
   if (prop != null) {
     Error e = Error.None;
     if (isTargetOfAssignment && !(prop.Type is Reference)) {
       Method setter = prop.Setter;
       if (setter == null) setter = prop.GetBaseSetter();
       if (setter == null) {
         e = Error.NoSetter;
       }
       else if (setter.IsAbstract && memberBinding.TargetObject is Base)
         e = Error.AbstractBaseCall;
     } else {
       if (prop.Getter == null) e = Error.NoGetter;
     }
     if (e != Error.None) {
       string typeName = this.GetTypeName(mem.DeclaringType);
       this.HandleError(memberBinding, e, typeName+"."+mem.Name);
       return null;
     }
   }
   TypeNode targetType = target == null ? null : TypeNode.StripModifiers(target.Type);
   bool errorIfCurrentMethodIsStatic = false;
   if (target is ImplicitThis) {
     errorIfCurrentMethodIsStatic = !(memType is BlockScope || memType is MethodScope); //locals and parameters are excempt
     if (errorIfCurrentMethodIsStatic && !this.NotAccessible(mem)) {
       if (this.MayNotReferenceThisFromFieldInitializer && this.currentMethod == null && this.currentField != null && !this.currentField.IsStatic) {
         this.HandleError(memberBinding, Error.ThisReferenceFromFieldInitializer, this.GetMemberSignature(mem));
         return null;
       }
       if (!this.GetTypeView(this.currentType).IsAssignableTo(memType)) {
         this.HandleError(memberBinding, Error.AccessToNonStaticOuterMember, this.GetTypeName(mem.DeclaringType), this.GetTypeName(this.currentType));
         return null;
       }
     }
     if (!this.MayReferenceThisAndBase && !(memType is Scope) && !this.insideInvariant) {
       this.HandleError(memberBinding, Error.ObjectRequired, this.GetMemberSignature(mem));
       return null;
     }
     targetType = null;
   } else if (target is Base || target is This) {
     if (!this.MayReferenceThisAndBase && !(this.insideInvariant && target is This)) {
       if (target is Base)
         this.HandleError(memberBinding, Error.BaseInBadContext, this.GetMemberSignature(mem));
       else
         this.HandleError(memberBinding, Error.ThisInBadContext, this.GetMemberSignature(mem));
       return null;
     }
     targetType = null;
     errorIfCurrentMethodIsStatic = true;
   } else if (!mem.IsStatic && target is Literal) {
     this.HandleError(memberBinding, Error.ObjectRequired, this.GetMemberSignature(mem));
     return null;
   } else if (target != null) {
     target = memberBinding.TargetObject = this.typeSystem.ExplicitCoercion(target, memType, this.TypeViewer);
     if (target == null) return null;
     if (prop != null && memType != null && memType.IsValueType)
       target = memberBinding.TargetObject = new UnaryExpression(target, NodeType.AddressOf, memType.GetReferenceType());
   }
   if (errorIfCurrentMethodIsStatic && 
     ((this.currentMethod != null && this.currentMethod.IsStatic) || (this.currentField != null && this.currentField.IsStatic))) {
     this.HandleError(memberBinding, Error.ObjectRequired, this.GetMemberSignature(mem));
     return null;
   }
   if (this.NotAccessible(mem, ref targetType)) {
     string mname = mem.Name.ToString();
     if (targetType == null && target != null && target.Type != null && !(target is ImplicitThis || target is This || target is Base))
       this.HandleError(memberBinding, Error.NotVisibleViaBaseType, this.GetTypeName(mem.DeclaringType)+"."+mname,
         this.GetTypeName(target.Type), this.GetTypeName(this.currentType));
     else if (mem.IsSpecialName && mem is Field && ((Field)mem).Type is DelegateNode)
       this.HandleError(memberBinding, Error.InaccessibleEventBackingField, this.GetTypeName(mem.DeclaringType) + "." + mname, this.GetTypeName(mem.DeclaringType));
     else {
       Node offendingNode = memberBinding;
       QualifiedIdentifier qi = memberBinding.BoundMemberExpression as QualifiedIdentifier;
       if (qi != null) offendingNode = qi.Identifier;
       this.HandleError(offendingNode, Error.MemberNotVisible, this.GetTypeName(mem.DeclaringType) + "." + mname);
       this.HandleRelatedError(mem);
     }
     return null;
   } else {
     string mname = mem.Name.ToString();
     if (!mem.IsCompilerControlled && (this.insideMethodContract  || this.insideInvariant)) {
       if (!this.AsAccessible(mem, currentMethod) && !this.insideInvariant) {
         this.HandleError(memberBinding, Error.MemberNotVisible, this.GetTypeName(mem.DeclaringType)+"."+mname);
         return null;
       }
       if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(mem, currentMethod)) {
         this.HandleError(memberBinding, Error.MemberMustBePureForMethodContract, this.GetTypeName(mem.DeclaringType)+"."+mname);
         return null;
       }
       if (this.insideInvariant  && !this.IsTransparentForInvariant(mem, currentMethod)) {
         this.HandleError(memberBinding, Error.MemberMustBePureForInvariant, this.GetTypeName(mem.DeclaringType)+"."+mname);
         return null;
       }
     } else if (!this.IsModelUseOk(mem, currentMethod)) {
       this.HandleError(memberBinding, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(mem.DeclaringType)+"."+mname);
       return null;
     }
   }
   Method meth = mem as Method;
   if (meth != null && memberBinding.Type != null && memberBinding.SourceContext.Document != null) {
     this.HandleError(memberBinding, Error.BadUseOfMethod, this.GetMethodSignature(meth));
     return null;
   }
   if (target != null) {
     TypeNode nt = mem as TypeNode;
     if (nt != null) {
       this.HandleError(memberBinding, Error.BadNestedTypeReference, mem.Name.ToString(), this.GetMemberSignature(mem));
       return null;
     }
   }
   Field f = mem as Field;
   if (isTargetOfAssignment && prop == null) {
     Error e = Error.BadLHSideForAssignment;
     if (f != null) {
       if (f.IsLiteral) {
         e = Error.AssignmentToLiteral;
       } else if (f.IsInitOnly) {
         e = Error.None;
         if (f.Type is Pointer && this.insideFixed && f.DeclaringType is BlockScope && !this.insideFixedDeclarator)
           e = Error.AssignmentToFixedVariable;
         else if (f.IsCompilerControlled && f.DeclaringType is BlockScope)
           f.Flags |= FieldFlags.Public;  //Do not give error on first assignment to controlled variable (such as foreach target var)
         else if ((f.DeclaringType != this.currentType && f.DeclaringType != null && !this.currentType.IsStructurallyEquivalentTo(f.DeclaringType.Template)) || 
         !((this.currentMethod is InstanceInitializer && (target is This || target is ImplicitThis)) ||
           (this.currentMethod is StaticInitializer && target == null))) {
           if (f.DeclaringType is BlockScope || f.DeclaringType is MethodScope)
             e = Error.AssignmentToReadOnlyLocal;
           else if (f.IsStatic)
             e = Error.AssignmentToReadOnlyStaticField;
           else
             e = Error.AssignmentToReadOnlyInstanceField;
         }
       } else if (target is MethodCall && target.Type.IsValueType) {
         MemberBinding mb = ((MethodCall)target).Callee as MemberBinding;
         if (mb != null) { e = Error.ResultIsNotReference; mem = mb.BoundMember; }
       } else if (isTargetOfAssignment && originalTarget is Construct && target.Type.IsValueType && mem is Field) {
         MemberBinding mb = ((Construct)originalTarget).Constructor as MemberBinding;
         if (mb != null) { e = Error.AssignmentHasNoEffect; mem = mb.BoundMember; }
       } else
         e = Error.None;
     } else if (mem is Event)
       e = Error.AssignmentToEvent;
     if (e != Error.None) {
       this.HandleError(memberBinding, e, this.GetMemberSignature(mem));
       return null;
     }
   }
   if (target != null) {
     if (mem.IsStatic) {
       this.HandleError(memberBinding, Error.TypeNameRequired, this.GetMemberSignature(mem));
       return null;
     }
   }
   this.CheckForObsolesence(memberBinding, mem);
   if (mem is Event) {
     this.HandleError(memberBinding, Error.BadUseOfEvent, this.GetMemberSignature(mem));
     return null;
   }
   if (f != null && f.IsLiteral)
     return this.typeSystem.ExplicitCoercion(f.DefaultValue, f.Type);
   return memberBinding;
 }
Example #12
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;
    }
Example #13
0
 public override Expression VisitMemberBinding(MemberBinding memberBinding){
   if (memberBinding == null) return null;
   Member member = memberBinding.BoundMember;
   if (member == null) return memberBinding;
   Method method = member as Method;
   if (method != null && method.Template != null && memberBinding.BoundMemberExpression is TemplateInstance){
     this.VisitResolvedReference(method, ((TemplateInstance)memberBinding.BoundMemberExpression).Expression);
     TypeNodeList templateArguments = ((TemplateInstance)memberBinding.BoundMemberExpression).TypeArgumentExpressions;
     this.VisitResolvedTypeReferenceList(method.TemplateArguments, templateArguments);
   }else
     this.VisitResolvedReference(memberBinding.BoundMember, memberBinding.BoundMemberExpression);
   return base.VisitMemberBinding(memberBinding);
 }
 /// <summary>
 /// Visits the children of <see cref="System.Linq.Expressions.MemberBinding"/>.
 /// </summary>
 /// <param name="node">The expression to visit.</param>
 /// <returns>The modified expression, if it or any subexpression was modified; otherwise,
 /// returns the original expression.</returns>
 protected override MemberBinding VisitMemberBinding(MemberBinding node)
 {
     throw new NotSupportedException($"Node type {node.GetType().Name} is not supported.");
 }
 void VisitMemberBindingMember(MemberBinding node)
 {
     WriteReference(node.Member.Name, node.Member);
     WriteSpace();
     WriteToken("=");
 }
Example #16
0
 protected abstract void WriteBinding(MemberBinding binding);
Example #17
0
        /// <summary>
        /// 查询数据源,并转化成TreeSelectListItem列表
        /// </summary>
        /// <typeparam name="T">数据源类型</typeparam>
        /// <param name="baseQuery">基础查询</param>
        /// <param name="dps">数据权限</param>
        /// <param name="whereCondition">条件语句</param>
        /// <param name="textField">表达式用来获取Text字段对应的值</param>
        /// <param name="valueField">表达式用来获取Value字段对应的值,不指定则默认使用Id字段</param>
        /// <param name="iconField">表达式用来获取icon字段对应的值</param>
        /// <param name="urlField">表达式用来获取Url字段对应的值</param>
        /// <param name="tagField">表达式用来获取Tag字段对应的值</param>
        /// <param name="expandField">表达式用来获取Expanded字段对应的值,指示节点是否展开</param>
        /// <param name="ignorDataPrivilege">忽略数据权限判断</param>
        /// <param name="SortByName">是否根据Text字段排序,默认为是</param>
        /// <returns>SelectListItem列表</returns>
        public static List <TreeSelectListItem> GetTreeSelectListItems <T>(this IQueryable <T> baseQuery
                                                                           , List <DataPrivilege> dps
                                                                           , Expression <Func <T, bool> > whereCondition
                                                                           , Expression <Func <T, string> > textField
                                                                           , Expression <Func <T, string> > valueField = null
                                                                           , Expression <Func <T, string> > iconField  = null
                                                                           , Expression <Func <T, string> > urlField   = null
                                                                           , Expression <Func <T, string> > tagField   = null
                                                                           , Expression <Func <T, bool> > expandField  = null
                                                                           , bool ignorDataPrivilege = false
                                                                           , bool SortByName         = true)
            where T : TopBasePoco, ITreeData <T>
        {
            var query = baseQuery;

            //如果条件不为空,则拼上条件
            if (whereCondition != null)
            {
                query = query.Where(whereCondition);
            }
            //如果没有指定忽略权限,则拼接权限过滤的where条件
            if (ignorDataPrivilege == false)
            {
                query = AppendSelfDPWhere(query, dps);
            }

            //处理后面要使用的expression
            if (valueField == null)
            {
                valueField = x => x.ID.ToString();
            }
            Expression <Func <T, string> > parentField = x => x.ParentId.ToString();

            //定义PE
            ParameterExpression pe = Expression.Parameter(typeof(T));
            ChangePara          cp = new ChangePara();

            //创建新类,形成类似 new SimpleTreeTextAndValue() 的表达式
            NewExpression newItem = Expression.New(typeof(TreeSelectListItem));

            //绑定Text字段,形成类似 Text = textField 的表达式
            var           textMI   = typeof(TreeSelectListItem).GetMember("Text")[0];
            MemberBinding textBind = Expression.Bind(textMI, cp.Change(textField.Body, pe));

            //绑定Value字段,形成类似 Value = valueField 的表达式
            var           valueMI   = typeof(TreeSelectListItem).GetMember("Id")[0];
            MemberBinding valueBind = Expression.Bind(valueMI, cp.Change(valueField.Body, pe));

            //绑定ParentId字段,形成类似 Value = valueField 的表达式
            var           parentMI   = typeof(TreeSelectListItem).GetMember("ParentId")[0];
            MemberBinding parentBind = Expression.Bind(parentMI, cp.Change(parentField.Body, pe));

            //绑定Url字段,形成类似 Value = valueField 的表达式
            MemberBinding urlBind = null;
            var           urlMI   = typeof(TreeSelectListItem).GetMember("Url")[0];

            if (urlField != null)
            {
                urlBind = Expression.Bind(urlMI, cp.Change(urlField.Body, pe));
            }
            else
            {
                urlBind = Expression.Bind(urlMI, Expression.Constant(string.Empty));
            }

            //绑定icon字段,形成类似 ICon = iconField 的表达式
            MemberBinding iconBind = null;
            var           iconMI   = typeof(TreeSelectListItem).GetMember("ICon")[0];

            if (iconField != null)
            {
                iconBind = Expression.Bind(iconMI, cp.Change(iconField.Body, pe));
            }
            else
            {
                iconBind = Expression.Bind(iconMI, Expression.Constant(string.Empty));
            }

            //绑定Tag字段,形成类似 Value = valueField 的表达式
            MemberBinding tagBind = null;
            var           tagMI   = typeof(TreeSelectListItem).GetMember("Tag")[0];

            if (tagField != null)
            {
                tagBind = Expression.Bind(tagMI, cp.Change(tagField.Body, pe));
            }
            else
            {
                tagBind = Expression.Bind(tagMI, Expression.Constant(""));
            }

            //绑定Tag字段,形成类似 Value = valueField 的表达式
            MemberBinding expandBind = null;
            var           expandMI   = typeof(TreeSelectListItem).GetMember("Expended")[0];

            if (expandField != null)
            {
                expandBind = Expression.Bind(expandMI, cp.Change(expandField.Body, pe));
            }
            else
            {
                expandBind = Expression.Bind(expandMI, Expression.Constant(false));
            }

            //合并创建新类和绑定字段的表达式,形成类似 new SimpleTextAndValue{ Text = textField, Value = valueField} 的表达式
            MemberInitExpression init = Expression.MemberInit(newItem, textBind, valueBind, iconBind, parentBind, urlBind, tagBind, expandBind);

            //将最终形成的表达式转化为Lambda,形成类似 x=> new SimpleTextAndValue { Text = x.textField, Value = x.valueField} 的表达式
            var lambda = Expression.Lambda <Func <T, TreeSelectListItem> >(init, pe);

            List <TreeSelectListItem> rv = null;

            //根据Text对下拉菜单数据排序
            if (SortByName == true)
            {
                rv = query.Select(lambda).OrderBy(x => x.Text).ToList();
            }
            else
            {
                rv = query.Select(lambda).ToList();
            }

            rv.ForEach(x =>
            {
                x.Children = rv.Where(y => y.ParentId == x.Id).ToList();
            });
            return(rv.Where(x => string.IsNullOrEmpty(x.ParentId)).ToList());
        }
Example #18
0
        /// <summary>
        /// 查询数据源,并转化成SelectListItem列表
        /// </summary>
        /// <typeparam name="T">数据源类型</typeparam>
        /// <param name="baseQuery">基础查询</param>
        /// <param name="dps">数据权限</param>
        /// <param name="whereCondition">条件语句</param>
        /// <param name="textField">SelectListItem中Text字段对应的值</param>
        /// <param name="valueField">SelectListItem中Value字段对应的值,默认为Id列</param>
        /// <param name="ignorDataPrivilege">忽略数据权限判断</param>
        /// <param name="SortByName">是否根据Text字段排序,默认为是</param>
        /// <returns>SelectListItem列表</returns>
        public static List <ComboSelectListItem> GetSelectListItems <T>(this IQueryable <T> baseQuery
                                                                        , List <DataPrivilege> dps
                                                                        , Expression <Func <T, bool> > whereCondition
                                                                        , Expression <Func <T, string> > textField
                                                                        , Expression <Func <T, string> > valueField = null
                                                                        , bool ignorDataPrivilege = false
                                                                        , bool SortByName         = true)
            where T : TopBasePoco
        {
            var query = baseQuery;

            //如果条件不为空,则拼上条件
            if (whereCondition != null)
            {
                query = query.Where(whereCondition);
            }
            //如果value字段为空,则默认使用Id字段作为value值
            if (valueField == null)
            {
                valueField = x => x.ID.ToString().ToLower();
            }

            //如果没有指定忽略权限,则拼接权限过滤的where条件
            if (ignorDataPrivilege == false)
            {
                query = AppendSelfDPWhere(query, dps);
            }

            //定义PE
            ParameterExpression pe = Expression.Parameter(typeof(T));
            ChangePara          cp = new ChangePara();
            //创建新类,形成类似 new SimpleTextAndValue() 的表达式
            NewExpression newItem = Expression.New(typeof(ComboSelectListItem));

            //绑定Text字段,形成类似 Text = textField 的表达式
            var           textMI   = typeof(ComboSelectListItem).GetMember("Text")[0];
            MemberBinding textBind = Expression.Bind(textMI, cp.Change(textField.Body, pe));


            //绑定Value字段,形成类似 Value = valueField 的表达式
            var           valueMI   = typeof(ComboSelectListItem).GetMember("Value")[0];
            MemberBinding valueBind = Expression.Bind(valueMI, cp.Change(valueField.Body, pe));

            //如果是树形结构,给ParentId赋值
            MemberBinding parentBind = null;
            var           parentMI   = typeof(ComboSelectListItem).GetMember("ParentId")[0];

            if (typeof(ITreeData <T>).IsAssignableFrom(typeof(T)))
            {
                var parentMember = Expression.MakeMemberAccess(pe, typeof(ITreeData).GetProperty("ParentId"));
                var p            = Expression.Call(parentMember, "ToString", new Type[] { });
                var p1           = Expression.Call(p, "ToLower", new Type[] { });
                parentBind = Expression.Bind(parentMI, p1);
            }
            else
            {
                parentBind = Expression.Bind(parentMI, Expression.Constant(string.Empty));
            }

            //合并创建新类和绑定字段的表达式,形成类似 new SimpleTextAndValue{ Text = textField, Value = valueField} 的表达式
            MemberInitExpression init = Expression.MemberInit(newItem, textBind, valueBind, parentBind);

            //将最终形成的表达式转化为Lambda,形成类似 x=> new SimpleTextAndValue { Text = x.textField, Value = x.valueField} 的表达式
            var lambda = Expression.Lambda <Func <T, ComboSelectListItem> >(init, pe);


            List <ComboSelectListItem> rv = new List <ComboSelectListItem>();

            //根据Text对下拉菜单数据排序
            if (SortByName == true)
            {
                rv = query.Select(lambda).OrderBy(x => x.Text).ToList();
            }
            else
            {
                rv = query.Select(lambda).ToList();
            }

            return(rv);
        }
Example #19
0
 protected BindingRewriter(MemberBinding memberBinding, StackSpiller stackSpiller)
 {
     MemberBinding = memberBinding;
     StackSpiller  = stackSpiller;
 }
Example #20
0
        protected override MemberBinding VisitMemberBinding(MemberBinding node)
        {
            _currentField = _target.StartBinding(node.Member);

            return(base.VisitMemberBinding(node));
        }
Example #21
0
 protected override MemberBinding VisitMemberBinding(MemberBinding node)
 {
     return(this.GiveUp(node));
 }
Example #22
0
 public override Expression VisitMemberBinding(MemberBinding memberBinding)
 {
     var result = base.VisitMemberBinding(memberBinding);
     var mb = result as MemberBinding;
     if (mb != null)
     {
         mb.BoundMember = this.VisitMemberReference(mb.BoundMember);
     }
     return result;
 }
 protected virtual void PVisitBinding(MemberBinding binding)
 {
 }
 public bool Equals(MemberBinding x, MemberBinding y)
 {
     return(this.eq.Equals(x, y));
 }
Example #25
0
 public virtual Expression OnInvalidMemberBinding(MemberBinding mb, QualifiedIdentifier qualId){
   return mb;
 }    
 public int GetHashCode(MemberBinding binding)
 {
     return(this.hash.GetHashCode(binding));
 }
Example #27
0
 public virtual Expression VisitBinaryExpression(BinaryExpression binaryExpression, Expression opnd1, Expression opnd2, TypeNode t1, TypeNode t2){
   if (binaryExpression == null){Debug.Assert(false); return null;}
   if (t1 == SystemTypes.String || t2 == SystemTypes.String) {
     switch (binaryExpression.NodeType) {
       case NodeType.Add:
         if (opnd1 is Literal && opnd2 is Literal && t1 == SystemTypes.String && t2 == SystemTypes.String) {
           string s1 = ((Literal)opnd1).Value as string;
           string s2 = ((Literal)opnd2).Value as string;
           return new Literal(s1 + s2, SystemTypes.String, binaryExpression.SourceContext);
         }
         Method operatorMethod = this.GetBinaryOperatorOverload(binaryExpression);
         if (operatorMethod != null) break;
         if (this.typeSystem.ImplicitCoercionFromTo(t1, SystemTypes.String, this.TypeViewer) && this.typeSystem.ImplicitCoercionFromTo(t2, SystemTypes.String, this.TypeViewer))
           return new MethodCall(new MemberBinding(null, Runtime.StringConcatStrings), new ExpressionList(opnd1, opnd2),
             NodeType.Call, SystemTypes.String, binaryExpression.SourceContext);
         else
           return new MethodCall(new MemberBinding(null, Runtime.StringConcatObjects), new ExpressionList(opnd1, opnd2),
             NodeType.Call, SystemTypes.String, binaryExpression.SourceContext);
       case NodeType.Eq:
       case NodeType.Ne:
         binaryExpression.Type = SystemTypes.Boolean;
         if (t1 == SystemTypes.String && t2 == SystemTypes.String)
           return this.StringValueComparison(binaryExpression);
         else if (t1 == SystemTypes.Object || t2 == SystemTypes.Object)
           return binaryExpression;
         else
           break;
     }
   }
   if ((t1 is DelegateNode) && (t2 is DelegateNode) && t1 != t2 && (binaryExpression.NodeType == NodeType.Eq || binaryExpression.NodeType == NodeType.Ne)) {
     this.HandleError(binaryExpression, Error.BadBinaryOps,
       binaryExpression.NodeType == NodeType.Eq ? "==" : "!=", this.GetTypeName(t1), this.GetTypeName(t2));
     return null;
   }
   if ((t1 != SystemTypes.Object && t2 != SystemTypes.Object) ||
     !(binaryExpression.NodeType == NodeType.Eq || binaryExpression.NodeType == NodeType.Ne) ||
     (t1.Template == SystemTypes.GenericBoxed || t2.Template == SystemTypes.GenericBoxed)){
     Method operatorMethod = this.GetBinaryOperatorOverload(binaryExpression);
     if (operatorMethod != null) {
       MemberBinding callee = new MemberBinding(null, operatorMethod);
       ExpressionList arguments = new ExpressionList(2);
       if (t1 == SystemTypes.Delegate && t2 is DelegateNode && (binaryExpression.NodeType == NodeType.Eq || binaryExpression.NodeType == NodeType.Ne)) {
         if (opnd1 is MemberBinding && ((MemberBinding)opnd1).BoundMember is Method)
           opnd1 = this.VisitExpression(new Construct(new MemberBinding(null, t2), new ExpressionList(opnd1)));
       }
       arguments.Add(opnd1);
       if (t1 is DelegateNode && t2 == SystemTypes.Delegate && (binaryExpression.NodeType == NodeType.Eq || binaryExpression.NodeType == NodeType.Ne)) {
         if (opnd2 is MemberBinding && ((MemberBinding)opnd2).BoundMember is Method)
           opnd2 = this.VisitExpression(new Construct(new MemberBinding(null, t1), new ExpressionList(opnd2)));
       }
       arguments.Add(opnd2);
       MethodCall call = new MethodCall(callee, arguments);
       call.SourceContext = binaryExpression.SourceContext;
       call.Type = operatorMethod.ReturnType;
       switch (binaryExpression.NodeType) {
         case NodeType.LogicalAnd:
         case NodeType.LogicalOr:
           binaryExpression.Operand1 = new Local(call.Type);
           binaryExpression.Operand2 = call;
           binaryExpression.Type = call.Type;
           return binaryExpression;
       }
       return call;
     }else if ((t1 == SystemTypes.String || t2 == SystemTypes.String) &&
       (binaryExpression.NodeType == NodeType.Eq || binaryExpression.NodeType == NodeType.Ne) &&
       this.typeSystem.ImplicitCoercionFromTo(t1, SystemTypes.String, this.TypeViewer) &&
       this.typeSystem.ImplicitCoercionFromTo(t2, SystemTypes.String, this.TypeViewer)){
       return this.StringValueComparison(binaryExpression);
     }
   }
   if (t1 is DelegateNode || t2 is DelegateNode){
     if (binaryExpression.NodeType == NodeType.Add || binaryExpression.NodeType == NodeType.Sub) {
       binaryExpression.Type = this.typeSystem.ImplicitCoercionFromTo(opnd1, t1, t2, this.TypeViewer) ? t2 : t1;
       return binaryExpression;
     }
   }
   if ((t1 is Pointer || t2 is Pointer) && (binaryExpression.NodeType == NodeType.Add || binaryExpression.NodeType == NodeType.Sub)){
     TypeNode elementType = t1 is Pointer ? ((Pointer)t1).ElementType : ((Pointer)t2).ElementType;
     Expression sizeOf = this.VisitUnaryExpression(new UnaryExpression(new Literal(elementType, SystemTypes.Type), NodeType.Sizeof, SystemTypes.UInt32));
     if (binaryExpression.NodeType == NodeType.Sub) {
       if (elementType == SystemTypes.Void) {
         this.HandleError(binaryExpression, Error.VoidError);
         return null;
       }
       if (t1 is Pointer && t2 is Pointer && ((Pointer)t1).ElementType == ((Pointer)t2).ElementType) {
         binaryExpression.Operand1 = new BinaryExpression(opnd1, new Literal(SystemTypes.Int64, SystemTypes.Type), NodeType.ExplicitCoercion, SystemTypes.Int64, opnd1.SourceContext);
         binaryExpression.Operand2 = new BinaryExpression(opnd2, new Literal(SystemTypes.Int64, SystemTypes.Type), NodeType.ExplicitCoercion, SystemTypes.Int64, opnd2.SourceContext);
         binaryExpression.Type = SystemTypes.Int64;
         return new BinaryExpression(binaryExpression, sizeOf, NodeType.Div, SystemTypes.Int64, binaryExpression.SourceContext);
       }
     }
     if (!(t1 is Pointer && t2 is Pointer)) {
       binaryExpression.Type = t1 is Pointer ? t1 : t2;
       if (elementType == SystemTypes.Void) {
         this.HandleError(binaryExpression, Error.VoidError);
         return null;
       }
       sizeOf.Type = SystemTypes.IntPtr;
       if (t1 is Pointer) {
         Literal lit = binaryExpression.Operand2 as Literal;
         if (lit == null || !(lit.Value is int) || ((int)lit.Value) != 1) {
           if (!(sizeOf is Literal) || !(((Literal)sizeOf).Value is int) || (int)((Literal)sizeOf).Value != 1) {
             if (binaryExpression.Operand2.Type == SystemTypes.Int32) binaryExpression.Operand2.Type = SystemTypes.IntPtr;
             binaryExpression.Operand2 = new BinaryExpression(binaryExpression.Operand2, sizeOf, NodeType.Mul, SystemTypes.IntPtr, binaryExpression.Operand2.SourceContext);
           }
         } else
           binaryExpression.Operand2 = sizeOf;
       } else {
         if (binaryExpression.NodeType == NodeType.Sub) return binaryExpression; //Let Checker issue a message
         Literal lit = binaryExpression.Operand1 as Literal;
         if (lit == null || !(lit.Value is int) || ((int)lit.Value) != 1) {
           if (!(sizeOf is Literal) || !(((Literal)sizeOf).Value is int) || (int)((Literal)sizeOf).Value != 1) {
             if (binaryExpression.Operand1.Type == SystemTypes.Int32) binaryExpression.Operand1.Type = SystemTypes.IntPtr;
             binaryExpression.Operand1 = new BinaryExpression(binaryExpression.Operand1, sizeOf, NodeType.Mul, SystemTypes.IntPtr, binaryExpression.Operand1.SourceContext);
           }
         } else
           binaryExpression.Operand1 = sizeOf;
       }
       return binaryExpression;
     }
   }
   binaryExpression.Type = this.InferTypeOfBinaryExpression(t1, t2, binaryExpression);
   if (binaryExpression.Operand1 == null || binaryExpression.Operand2 == null) binaryExpression.IsErroneous = true;
   try{
     bool savedCheckOverflow = this.typeSystem.checkOverflow;
     this.typeSystem.checkOverflow = !this.typeSystem.suppressOverflowCheck;
     MemberBinding mb = opnd1 as MemberBinding;
     if (mb != null && mb.Type == SystemTypes.Delegate && mb.BoundMember is Method && binaryExpression.NodeType == NodeType.Is) { return Literal.False; }
     Literal lit = PureEvaluator.EvalBinaryExpression(this.EvaluateAsLiteral(opnd1), this.EvaluateAsLiteral(opnd2), binaryExpression, this.typeSystem);
     this.typeSystem.checkOverflow = savedCheckOverflow;
     if (lit != null){
       if (binaryExpression.Type != lit.Type) {
         EnumNode enType = binaryExpression.Type as EnumNode;
         if (enType != null && this.typeSystem.ImplicitCoercionFromTo(lit, lit.Type, enType.UnderlyingType, this.TypeViewer))
           lit.Type = enType;
         else if (binaryExpression.Type == SystemTypes.Single && lit.Type == SystemTypes.Double)
           lit.Type = SystemTypes.Single;
         else if (binaryExpression.Type is EnumNode && ((EnumNode)binaryExpression.Type).UnderlyingType == SystemTypes.UInt32 &&
           lit.Type == SystemTypes.Int64 && ((long)lit.Value) <= uint.MaxValue)
           lit = new Literal((uint)(long)lit.Value, SystemTypes.UInt32);
         else if (binaryExpression.Type == SystemTypes.Int64 && lit.Type == SystemTypes.UInt64)
           binaryExpression.Type = SystemTypes.UInt64;
       }
       lit.SourceExpression = binaryExpression;
       lit.SourceContext = binaryExpression.SourceContext;
       if (binaryExpression.NodeType == NodeType.ExplicitCoercion){
         lit.SourceExpression = opnd1;
         lit.TypeWasExplicitlySpecifiedInSource = true;
       }
       return lit;
     }
   }catch (OverflowException){
     if (binaryExpression.Type is EnumNode && this.currentField != null) {
       this.HandleError(binaryExpression, Error.EnumerationValueOutOfRange, this.GetMemberSignature(this.currentField));
       return Literal.Int32Zero;
     }
     this.HandleError(binaryExpression, Error.CTOverflow);
     return null;
   }catch{} //TODO: be more specific
   return binaryExpression;
 }
 protected static void CannotOptimize(MemberBinding binding)
 {
     throw new QueryOptimizationException(binding.ToString());
 }
Example #29
0
 public override Expression VisitMemberBinding(MemberBinding memberBinding) {
   return this.VisitMemberBinding(memberBinding, false);
 }
 protected override MemberBinding VisitMemberBinding(MemberBinding node)
 {
     Combine(node.BindingType);
     Combine(node.Member);
     return(base.VisitMemberBinding(node));
 }
Example #31
0
    public override TypeNode VisitTypeNode(TypeNode typeNode) {
      if (typeNode == null) return null;
      TypeNode savedCurrentType = this.currentType;
      if (typeNode.IsNormalized) {
        this.currentType = this.typeSystem.currentType = typeNode;
        this.VisitMemberList(typeNode.Members);
        this.currentType = this.typeSystem.currentType = savedCurrentType;
        return typeNode;
      }
      if (typeNode.Template == this.currentType && typeNode.IsNotFullySpecialized) return typeNode;
      if (typeNode.PartiallyDefines != null) {
        if (this.visitedCompleteTypes == null) this.visitedCompleteTypes = new TrivialHashtable();
        if (this.visitedCompleteTypes[typeNode.PartiallyDefines.UniqueKey] == null) {
          this.VisitTypeNode(typeNode.PartiallyDefines);
          this.visitedCompleteTypes[typeNode.PartiallyDefines.UniqueKey] = typeNode;
        }
        return typeNode;
      }
      typeNode.Attributes = this.VisitAttributeList(typeNode.Attributes);
      //Flatten interface list
      InterfaceList interfaces = this.GetTypeView(typeNode).Interfaces;
      for (int i = 0, n = interfaces == null ? 0 : interfaces.Count; i < n; i++) {
        Interface iface = interfaces[i];
        if (iface == null || iface is TypeParameter) continue;
        if (this.GetTypeView(iface).IsAssignableTo(typeNode)) {
          this.HandleError(typeNode.Name, Error.CycleInInterfaceInheritance, this.GetTypeName(iface), this.GetTypeName(typeNode));
          if (iface != typeNode) this.HandleRelatedError(iface);
          for (int j = i; j < n-1; j++)
            interfaces[j] = interfaces[j+1];
          interfaces.Count = n-1;
          continue;
        }
        if (typeNode.NodeType == NodeType.Interface) {
          if (this.IsLessAccessible(iface, typeNode)) {
            this.HandleError(typeNode.Name, Error.BaseInterfaceLessAccessible, this.GetTypeName(iface), this.GetTypeName(typeNode));
            this.HandleRelatedError(iface);
          }
        }
        InterfaceList inheritedInterfaces = this.GetTypeView(iface).Interfaces;
        int m = inheritedInterfaces == null ? 0 : inheritedInterfaces.Count;
        for (int j = 0; j < m; j++) {
          Interface iiface = inheritedInterfaces[j];
          if (iiface == null) continue;
          bool mustAddInterface = true;
          for (int k = 0; k < n; k++) {
            if (interfaces[k] == iiface) {
              mustAddInterface = false;
              break;
            }
          }
          if (mustAddInterface) {
            interfaces.Add(iiface);
            n++;
          }
        }
      }
      typeNode.Attributes = this.VisitAttributeList(typeNode.Attributes, typeNode);
      this.currentType = this.typeSystem.currentType = typeNode;
      this.CheckHidingAndOverriding(typeNode);            
      #region Deal with modelfields that are inherited from implemented interfaces.
      if (typeNode is Class) {
        StringCollection implementedModelfields = new StringCollection(); //contains the names of modelfields implemented so far
        foreach (Interface implInterface in typeNode.Interfaces) {
          if (implInterface == null) continue; //Why is Interfaces initialized to a List with a single null element? Means this check is essential.
          if (implInterface.Contract != null)
          {
            foreach (ModelfieldContract mfCToImplement in implInterface.Contract.ModelfieldContracts)
            {
              #region implement mfCToImplement in typeNode
              String fieldnameToImplement = mfCToImplement.Modelfield.Name.Name;
              if (implementedModelfields.Contains(fieldnameToImplement))
              {
                this.HandleError(typeNode, Error.GenericError, "Class " + typeNode.Name.Name + " cannot implement two interfaces that both define a model field " + fieldnameToImplement);
                continue; //ignore this contract
                //Disallowed to prevent the unexpected modification of a modelfield in one interface by changing a modelfield in another interface.              
              }
              else
              {
                implementedModelfields.Add(fieldnameToImplement);
                ModelfieldContract mfCThatImplements = null; //represents the contract that will implement mfCToImplement
                Member implementingMember = null;
                #region if typeNode or a superclass already defines a member named fieldNameToImplement, store it in implementingMember.
                for (TypeNode classWithField = typeNode; classWithField != null && implementingMember == null; classWithField = classWithField.BaseType)
                {
                  MemberList members = this.GetTypeView(classWithField).GetMembersNamed(mfCToImplement.Modelfield.Name);
                  foreach (Member m in members)
                  {
                    if (m.Name.Name == fieldnameToImplement)
                    {
                      implementingMember = m;
                      break; //implementing member found; stop looking
                    }
                  }
                }
                #endregion
                #region if there is an implentingMember: if it is a modelfield in typeNode, then store its contract in mfCThatImplements, else complain
                if (implementingMember != null && implementingMember.DeclaringType != typeNode)
                {
                  this.HandleError(typeNode, Error.GenericError, "Class " + typeNode.Name.Name + " does not define a model field " + fieldnameToImplement + " that implements " + mfCToImplement.Modelfield.FullName + " and hides " + implementingMember.FullName);
                  this.HandleRelatedError(mfCToImplement.Modelfield);
                  this.HandleRelatedError(implementingMember);  //TODO: suppress error typeNode does not implement implInterface.fieldnameToImplement.get
                  continue; //ignore this contract
                  //Disallowed to prevent the unexpected modification of a superclass member by changing a modelfield in an interface/the unexpected hiding of a superclass member by a modelfield in an interface.
                }
                if (implementingMember != null && !(implementingMember is Field && (implementingMember as Field).IsModelfield))
                {
                  this.HandleError(typeNode, Error.GenericError, "Class " + typeNode.Name.Name + " cannot implement " + mfCToImplement.Modelfield.FullName + " as it contains a non-modelfield member of that name");
                  this.HandleRelatedError(mfCToImplement.Modelfield);
                  this.HandleRelatedError(implementingMember); //TODO: suppress error typeNode does not implement implInterface.fieldnameToImplement.get
                  continue; //ignore this contract
                }
                if (implementingMember != null)
                {
                  //typeNode defines a modelfield (i.e., implementingMember) that can implement mfCToImplement
                  Debug.Assert(typeNode.Contract != null); //a class that defines a modelfield must have a modelfieldcontract that applies to it. 
                  foreach (ModelfieldContract mfC in typeNode.Contract.ModelfieldContracts)
                    if (mfC.Modelfield == implementingMember)
                    {
                      mfCThatImplements = mfC;
                      break;
                    }
                  Debug.Assert(mfCThatImplements != null);
                }
                #endregion
                #region if there is no implementingMember: add a new modelfield + contract to typeNode and store contract in mfCThatImplements
                //TODO: Unfortunately, qualified identifiers have already been resolved: currently references to the modelfield will produce an error. 
                if (implementingMember == null)
                {
                  Identifier mfIdent = new Identifier(mfCToImplement.Modelfield.Name.Name);
                  mfCThatImplements = new ModelfieldContract(typeNode, new AttributeList(), mfCToImplement.ModelfieldType, mfIdent, typeNode.SourceContext);
                  Field mf = (mfCThatImplements.Modelfield as Field);
                  mf.SourceContext = mfCToImplement.SourceContext; //the modelfield does not appear in the code but implements mfCToImplement.
                  typeNode.Members.Add(mf);
                  if (typeNode.Contract == null)
                    typeNode.Contract = new TypeContract(typeNode);
                  typeNode.Contract.ModelfieldContracts.Add(mfCThatImplements);
                }
                #endregion
                #region Implement the property and property getter that represent mfCToImplement, let getter return mfCThatImplements.Modelfield
                //assert typeNode.Contract.ModelfieldContracts.Contains(mfCThatImplements); 
                //create Property:
                //  public <mfCThatImplements.ModelfieldType> <mfCThatImplements.Modelfield.Name>
                //    ensures result == <mfCThatImplements.Modelfield>;
                //  { [Confined] get { return <mfCThatImplements.Modelfield>; }  } 
                //  Note that getter needs to be confined because it inherits NoDefaultContract
                MemberBinding thisMf = new MemberBinding(new This(typeNode), mfCThatImplements.Modelfield);
                Statement ret = new Return(thisMf);
                Method getter = new Method(typeNode, new AttributeList(), (mfCToImplement.Modelfield as Property).Getter.Name, new ParameterList(), mfCThatImplements.ModelfieldType, new Block(new StatementList(ret)));
                getter.Flags = MethodFlags.Public;
                getter.CallingConvention = CallingConventionFlags.HasThis;
                if (getter.Contract == null)
                {
                  getter.Contract = new MethodContract(getter);
                }
                Expression resultOfGet = new ReturnValue(getter.ReturnType, mfCToImplement.SourceContext);
                BinaryExpression b = new BinaryExpression(resultOfGet, thisMf, NodeType.Eq, mfCToImplement.SourceContext);
                b.Type = SystemTypes.Boolean;
                //Give getter Confined (as it has NoDefaultContract)
                // That means make it [Pure][Reads(Reads.Owned)]
                InstanceInitializer pCtor = SystemTypes.PureAttribute.GetConstructor();
                if (pCtor != null)
                  getter.Attributes.Add(new AttributeNode(new MemberBinding(null, pCtor), null, AttributeTargets.Method));
                InstanceInitializer rCtor = SystemTypes.ReadsAttribute.GetConstructor(); // can use nullary ctor since default is confined
                if (rCtor != null)
                  getter.Attributes.Add(new AttributeNode(new MemberBinding(null, rCtor), null, AttributeTargets.Method));

                getter.Contract.Ensures.Add(new EnsuresNormal(b));
                Identifier implPropName = new Identifier(mfCToImplement.Modelfield.FullName, mfCToImplement.SourceContext); //use full name as typeNode might define modelfield with this name itself.
                Property implementingProperty = new Property(typeNode, new AttributeList(), PropertyFlags.None, implPropName, getter, null);
                typeNode.Members.Add(implementingProperty);
                typeNode.Members.Add(getter);
                #endregion
                #region Copy the info from mfCToImplement to typeNode's mfCThatImplements
                foreach (Expression satClause in mfCToImplement.SatisfiesList)
                  mfCThatImplements.SatisfiesList.Add(satClause);
                //Don't copy the explicit witness from the implemented contract: can likely infer a better one.
                #endregion
              }
              #endregion
            }
          }
        }
      }
      #endregion //needs to happen after CheckHidingAndOverriding, but before CheckAbstractMethods.
      this.CheckAbstractMethods(typeNode); //TODO: suppress duplicate errors generated by template instances
      this.CheckCircularDependency(typeNode);
      this.CheckForDuplicateDeclarations(typeNode);
      // must do this *after* CheckForDuplicateDeclarations
      this.CheckForInterfaceImplementationsOfOutOfBandContractedMethods(typeNode);      
      this.CheckOperatorOverloads(typeNode);
      if (typeNode is Class && typeNode.IsSealed)
        this.CheckForNewFamilyOrVirtualMembers(typeNode);
      this.VisitTemplateInstanceTypes(typeNode);
      this.CheckContractInheritance(typeNode);      
      TypeNode result = base.VisitTypeNode(typeNode);           
      
      #region infer and serialize witnesses where needed (for modelfields and pure methods). ALSO infers postconditions.
      if (this.currentOptions != null && !this.currentOptions.DisablePublicContractsMetadata && !this.currentOptions.DisableInternalContractsMetadata) {
        //Note that this code could move to the boogie end, except that we need a runtime witness for modelfields.      
        //We need to show that the contract of a modelfield mf is consistent in order to use the associated axioms.
        //An inferred witness is a guess at an expression e that will satisfy the contract, i.e., 
        //an expression e such that for each satisfies clause p, p[e/mf] holds. Checking this witness is left to Boogie.
        if (typeNode.Contract != null) {
          foreach (ModelfieldContract mfC in typeNode.Contract.ModelfieldContracts) {
            if (mfC.ModelfieldType == null) continue; //signals error, but will be reported elsewhere
            Expression satisfies = null;
            foreach (Expression sat in mfC.SatisfiesList) { //construct a single expression to take advantage of the fact that multiple clauses act as an &&
              if (sat == null) continue;
              if (satisfies == null)
                satisfies = sat;
              else
                satisfies = new BinaryExpression(sat, satisfies, NodeType.LogicalAnd, SystemTypes.Boolean);
            }
            WUCs witnesses = Checker.GetWitnesses(satisfies, mfC.Modelfield, mfC.ModelfieldType);
            this.SerializeWUCs(witnesses, mfC); //also serializes explicitly specified witnesses.
            if (mfC.Witness == null) {  //we need to set a witness as runtime witness (do this afterwards as it will be serialized otherwise)
              //But as we have only one runtime witness, we can't guarantuee that we pick the right one. For now, just hope for the best.
              if (witnesses.RuntimeWitness != null)
                mfC.Witness = witnesses.RuntimeWitness;
              else
                mfC.Witness = this.GetInferredWitness(mfC); //this calculates a runtime witness 
            }
          }
        }
        foreach (Member m in typeNode.Members) {
          Method method = m as Method;
          if (method == null || method.ReturnType == null) continue;
          if (!method.IsPure && !method.IsConfined && !method.IsStateIndependent) continue;
          if (method.CciKind != CciMemberKind.Regular) continue; //no need to check consistency of methodology method contracts
          if (method.ReturnType == SystemTypes.Void) continue; //no witness needed for void        
          #region infer potential method contract witnesses and add them as WitnessAttributes
          //A pure method can be used in specifications and assert statements. 
          //Therefore, we need to show that the contract of a pure method is consistent in order to use purity axioms.
          //An inferred witness is a guess at an expression e that will satisfy all postconditions, i.e., 
          //an expression e such that for each postcondition p, p[e/result] holds. Checking this witness is left to Boogie.                
          Expression postcondition = null;
          if (method.Contract != null) {
            foreach (Ensures ens in method.Contract.Ensures) {
              if (ens.PostCondition != null) {
                if (postcondition == null)
                  postcondition = ens.PostCondition;
                else
                  postcondition = new BinaryExpression(ens.PostCondition, postcondition, NodeType.LogicalAnd, SystemTypes.Boolean);
              }
            }
          }
          WUCs witnesses = Checker.GetWitnesses(postcondition, null, method.ReturnType);
          #region find witnesses in method code and infer postconditions
          if (method.Body != null && method.Body.Statements != null) {
            WitnessFromCodeFinderVisitor codeWitnessFinder = new WitnessFromCodeFinderVisitor();
            if (!method.IsVirtual && //don't infer postcondition: the absence might be intentional, to give overriding method more freedom               
                (method.Contract == null || method.Contract.Ensures.Count == 0)) //don't infer post if user specified a postcondition
          { //look for inferred postconditions
              codeWitnessFinder.methodToInferPostFrom = method;
            }
            codeWitnessFinder.VisitStatementList(method.Body.Statements);
            if (method.ReturnType != SystemTypes.Boolean && method.ReturnType.NodeType != NodeType.EnumNode) //check if all possible witnesses have already been added, finder was only run to infer postconditions
              foreach (Expression witness in codeWitnessFinder.Witnesses)
                witnesses.Exact.Add(new WitnessUnderConstruction(witness, null, 0));
          }
          #endregion
          this.SerializeWUCs(witnesses, method);
          #endregion
        }
      }
      #endregion

      // do this here so the serialized contracts reflect any modifications made during Checker
      // serialized contracts should be pre-Normalized ASTs, *but* they should not reflect
      // any contract inheritance that has happened.
      // Note that this (possibly) adds things to the Attributes of the typeNode
      // Those attribute nodes will not be checked as part of Checker
      this.SerializeContracts(typeNode);
      

      this.currentType = this.typeSystem.currentType = savedCurrentType;
      return result;
    }
Example #32
0
 public override Expression VisitApplyToAll(ApplyToAll applyToAll) {
   if (applyToAll == null) return null;
   Expression collection = applyToAll.Operand1;
   if (collection == null) { Debug.Assert(false); return null; }
   TypeNode elemType = this.typeSystem.GetStreamElementType(collection.Type, this.TypeViewer);
   bool singleTon = elemType == collection.Type;
   Local loc = applyToAll.ElementLocal;
   if (loc == null) loc = new Local(elemType);
   if (singleTon)
     applyToAll.Operand1 = this.VisitExpression(collection);
   else
     applyToAll.Operand1 = this.VisitEnumerableCollection(collection, loc.Type);
   if (applyToAll.Operand1 == null) return null;
   AnonymousNestedFunction func = applyToAll.Operand2 as AnonymousNestedFunction;
   Expression expr = applyToAll.Operand2 as BlockExpression;
   if (func != null || expr != null) {
     this.VisitAnonymousNestedFunction(func);
     if (singleTon || applyToAll.Type == SystemTypes.Void) return applyToAll;
     //Create an iterator to compute stream that results from ApplyToAll
     Class closureClass = this.currentMethod.Scope.ClosureClass;
     Method method = new Method();
     method.Name = Identifier.For("Function:"+method.UniqueKey);
     method.SourceContext = collection.SourceContext;
     method.Flags = MethodFlags.CompilerControlled;
     method.CallingConvention = CallingConventionFlags.HasThis;
     method.InitLocals = true;
     method.DeclaringType = closureClass;
     closureClass.Members.Add(method);
     method.Scope = new MethodScope(new TypeScope(null, closureClass), null);
     Parameter coll = new Parameter(StandardIds.Collection, collection.Type);
     ParameterField fcoll = new ParameterField(method.Scope, null, FieldFlags.CompilerControlled, StandardIds.Collection, collection.Type, null);
     fcoll.Parameter = coll;
     method.Scope.Members.Add(fcoll);
     Parameter closure = new Parameter(StandardIds.Closure, closureClass);
     ParameterField fclosure = new ParameterField(method.Scope, null, FieldFlags.CompilerControlled, StandardIds.Closure, closureClass, null);
     fclosure.Parameter = closure;
     if (func != null) {
       method.Scope.Members.Add(fclosure);
       method.Parameters = new ParameterList(coll, closure);
     } else
       method.Parameters = new ParameterList(coll);
     method.ReturnType = applyToAll.Type;
     ForEach forEach = new ForEach();
     forEach.TargetVariable = loc;
     forEach.TargetVariableType = loc.Type;
     forEach.SourceEnumerable = new MemberBinding(new ImplicitThis(), fcoll);
     if (func != null) {
       MemberBinding mb = new MemberBinding(new MemberBinding(new ImplicitThis(), fclosure), func.Method);
       expr = new MethodCall(mb, new ExpressionList(loc), NodeType.Call, func.Method.ReturnType, func.SourceContext);
     } else
       expr = this.VisitExpression(expr);
     expr = this.typeSystem.ImplicitCoercion(expr, this.typeSystem.GetStreamElementType(applyToAll.Type, this.TypeViewer), this.TypeViewer);
     if (expr == null) return null;
     BlockExpression bExpr = expr as BlockExpression;
     if (bExpr != null && bExpr.Type == SystemTypes.Void)
       forEach.Body = bExpr.Block;
     else
       forEach.Body = new Block(new StatementList(new Yield(expr)));
     forEach.ScopeForTemporaryVariables = new BlockScope(method.Scope, forEach.Body);
     method.Body = new Block(new StatementList(forEach));
     applyToAll.ResultIterator = this.VisitMethod(method);
     return applyToAll;
   }
   Debug.Assert(false);
   return null;
 }
Example #33
0
      public Method methodToInferPostFrom = null;  //if set, Visit tries to infer a postcondition for method. 

      public override StatementList VisitStatementList(StatementList statements) {
        if (statements == null) return null;
        foreach (Statement stat in statements) {
          Return r = stat as Return;
          if (r != null && r.Expression != null) { //Statement return E; found. Test admissibility of E as a witness.
            WitnessFromCodeAdmissibilityVisitor admis = new WitnessFromCodeAdmissibilityVisitor();            
            try {
              admis.VisitExpression(r.Expression);
              this.Witnesses.Add(r.Expression); //witness found, otherwise exception would have been thrown
              
              #region add inferred postconditions if needed
              TypeNode retType = (methodToInferPostFrom == null || methodToInferPostFrom.ReturnType == null) ? null : methodToInferPostFrom.ReturnType;              
              if (r == statements[0] && retType != null && (retType.IsObjectReferenceType || retType.IsPrimitiveComparable)) {
                //the return statement is the first statement of the body.
                //We would like to add ensures result == r.Expression; However, we have to be careful, for 2 reasons.
                //1: == cannot be applied to structs and generic types. Note that we already tested that we do not return a struct.
                //2: result might be the implicitly boxed version of r.Expression (e.g., public object m() {returns 5;}), in which case result == r.Expression does not hold (in particular at runtime)
                //To account for 2, we have to box/unbox result and r.Expression as necessary
                //If r.Expression is a generic type, we have to distinguish cases !(r.Expression is System.ValueType) or (r.Expression is int) and act accordingly                              
                //(We do not (yet) support cases where r.Expression is a valueType other than an int, but they could be handled along the same lines.)

                if (methodToInferPostFrom.Contract == null) {
                  methodToInferPostFrom.Contract = new MethodContract(methodToInferPostFrom);
                }
                SourceContext scInferred = methodToInferPostFrom.Name.SourceContext; //can't set the sourcetext, so error message will be confusing...but then again, the idea is that this can never crash                                                                                
                
                //Duplicate the return expression to avoid sharing problems 
                Duplicator dup = new Duplicator(this.methodToInferPostFrom.DeclaringType.DeclaringModule, this.methodToInferPostFrom.DeclaringType);
                Expression returnInEq = dup.VisitExpression(r.Expression);

                //needed for casting/boxing/unboxing
                MemberBinding intType = new MemberBinding(null, SystemTypes.Int32);
                Literal objectLit = new Literal(SystemTypes.Object, SystemTypes.Type);
                Literal intLit = new Literal(SystemTypes.Int32, SystemTypes.Type);

                Expression resultBinding = new ReturnValue(methodToInferPostFrom.ReturnType, scInferred);
                Expression resultInEq = resultBinding;
                if (r.Expression.NodeType == NodeType.Box) { //if the return expression has been (implicitly) boxed, unbox both it and result
                  returnInEq = (returnInEq as BinaryExpression).Operand1; //as we have the return expression in hand, unboxing is easy
                  //adjust resultInEq to (returnInEq.Type)resultInEq (i.e., add an unbox), using an explicit coercion
                  BinaryExpression resultUnboxed = new BinaryExpression(resultInEq, intType, NodeType.Unbox, SystemTypes.Int32.GetReferenceType(), scInferred); //gets type System.Int32@ 
                  AddressDereference resultDeref = new AddressDereference(resultUnboxed, returnInEq.Type, scInferred);
                  resultInEq = new BinaryExpression(resultDeref, intLit, NodeType.ExplicitCoercion, SystemTypes.Int32, scInferred);
                }
                                
                if (returnInEq.Type != null && (returnInEq.Type.IsObjectReferenceType || returnInEq.Type.IsPrimitiveComparable)) {
                  //returnInEq is not a user-defined struct (to which we can't apply ==)
                  Expression eq = null; //holds the postcondition that is added
                  if (!(isGenericTypeThatCanBeStruct(returnInEq.Type))) {
                    //== can be applied to returnInEq. Therefore, it can also be applied to resultInEq, which is of a supertype (i.e., not generic type, not a struct). 
                    eq = new BinaryExpression(resultInEq, returnInEq, NodeType.Eq, SystemTypes.Boolean, scInferred);
                  } else {
                    #region adjust eq to compensate for generics 
                    //insert  ensures !(returnInEq is System.ValueType) ==> (object)resultInEq == (object)returnInEq;
                    //and     ensures returnInEq is int ==> (int)(object)resultInEq == (int)(object)returnInEq;
                    //the cast to object is needed to allow application of == and the cast to int. 
                    //Note that resultInEq.Type is known to also be a generic type as it is a supertype.
                    //(and note that in this case, there was no unboxing)

                    #region set up the antecedent !(returnInEq is System.ValueType)
                    TypeNode theType = SystemTypes.ValueType;

                    //antecedent: !(r.Expression is System.ValueType)
                    Expression ante = new BinaryExpression(r.Expression, new Literal(theType, SystemTypes.Type), NodeType.Is, SystemTypes.Boolean, scInferred);
                    ante = new UnaryExpression(ante, NodeType.LogicalNot, SystemTypes.Boolean, scInferred);
                    #endregion

                    #region adjust resultInEq and returnInEq to (object)resultInEq and (object)returnInEq
                    //adjust resultInEq to (object)result, so that it can be used in ==
                    //that means Box it to T, then ExplicitCast it to Object.
                    MemberBinding boxType = new MemberBinding(null, returnInEq.Type); //could also use method return type
                    BinaryExpression resultBoxed = new BinaryExpression(resultBinding, boxType, NodeType.Box, returnInEq.Type, scInferred);
                    resultInEq = new BinaryExpression(resultBoxed, objectLit, NodeType.ExplicitCoercion, SystemTypes.Object, scInferred);
                    
                    //adjust returnInEq to (object)returnInEq                    
                    BinaryExpression returnBoxed = new BinaryExpression(returnInEq, boxType, NodeType.Box, returnInEq.Type, scInferred);
                    returnInEq = new BinaryExpression(returnBoxed, objectLit, NodeType.ExplicitCoercion, SystemTypes.Object, scInferred);
                    #endregion

                    //Add first ensures; ensures ante ==> resultInEq == returnInEq;
                    eq = new BinaryExpression(resultInEq, returnInEq, NodeType.Eq, SystemTypes.Boolean, scInferred);
                    Expression impl = new BinaryExpression(ante, eq, NodeType.Implies, scInferred);
                    EnsuresNormal firstPost = new EnsuresNormal(impl);
                    firstPost.SourceContext = scInferred;
                    methodToInferPostFrom.Contract.Ensures.Add(firstPost);

                    //Now add ensures returnInEq is int ==> (int)(object)resultInEq == (int)(object)returnInEq;
                    //antecedent: r.Expression is int                
                    Expression secondAnte = new BinaryExpression(r.Expression, intLit, NodeType.Is, SystemTypes.Boolean, scInferred);

                    #region adjust resultInEq and returnInEq to (int)resultInEq and (int)returnInEq
                    //set resultInSecondEq to (int)resultInEq, i.e., to (int)(object)result
                    //this requires an unbox to int32@, then an adress-deref to int32, then an explicitcast to int32
                    //note that if we unbox to type Int32 directly, we get a "operation could destabilize the runtime" warining from the checkin tests
                    BinaryExpression resultUnboxed = new BinaryExpression(resultInEq, intType, NodeType.Unbox, SystemTypes.Int32.GetReferenceType(), scInferred); //gets type System.Int32@ 
                    AddressDereference resultDeref = new AddressDereference(resultUnboxed, SystemTypes.Int32, scInferred);
                    BinaryExpression resultInSecondEq = new BinaryExpression(resultDeref, intLit, NodeType.ExplicitCoercion, SystemTypes.Int32, scInferred);

                    //adjust returnInEq to (int)returnInEq 
                    BinaryExpression returnUnboxed = new BinaryExpression(returnInEq, intType, NodeType.Unbox, SystemTypes.Int32.GetReferenceType(), scInferred);
                    AddressDereference returnDeref = new AddressDereference(returnUnboxed, SystemTypes.Int32, scInferred);
                    BinaryExpression returnInSecondEq = new BinaryExpression(returnDeref, intLit, NodeType.ExplicitCoercion, SystemTypes.Int32, scInferred);
                    #endregion
                    
                    Expression secondEq = new BinaryExpression(resultInSecondEq, returnInSecondEq, NodeType.Eq, SystemTypes.Boolean, scInferred);
                    eq = new BinaryExpression(secondAnte, secondEq, NodeType.Implies, SystemTypes.Boolean, scInferred); //(Ab)use eq to hold the implication 
                    #endregion
                  }
                  //Add the constructed equality as a postcondition.
                  EnsuresNormal newPost = new EnsuresNormal(eq);
                  newPost.SourceContext = scInferred;
                  methodToInferPostFrom.Contract.Ensures.Add(newPost);  
                } //else don't generate a postcondition, can't apply == to a user-defined struct                 
              }
              #endregion
            }
            catch (ApplicationException e) { ApplicationException dumme = e; } //witness not admissible ('using' e to avoid warning)           
          }
        }
        return statements;
      }
Example #34
0
		public virtual Expression VisitMemberBinding (MemberBinding node)
		{
			if (node == null)
				return null;

			node.TargetObject = VisitExpression (node.TargetObject);

			return node;
		}
Example #35
0
 /// <summary>
 /// <para>
 /// Serializes the expressions in toSerialize to an attribute determined by ctor, as if they come from module containingModule.
 /// Uses the SourceContext information of <param name="sc">sc</param> for the source context for the attribute.
 /// </para>
 /// <para><code>
 /// requires ctor != null &amp;&amp; sc != null;
 /// </code></para>
 /// <para><code>
 /// requires ctor.DeclaringType &lt;: Microsoft.Contracts.AttributeWithContext;
 /// </code></para>
 /// </summary>
 /// <returns></returns>
 public static AttributeNode SerializeExpressions(InstanceInitializer/*!*/ ctor, ExpressionList dontSerialize, ExpressionList toSerialize, SourceContext/*!*/ sc, Module containingModule) {
   MemberBinding attrBinding = new MemberBinding(null, ctor);
   ExpressionList args = new ExpressionList();
   if (dontSerialize != null) {
     foreach (Expression e in dontSerialize) {
       args.Add(e);
     }
   }
   if (toSerialize != null) {
     foreach (Expression e in toSerialize) {
       ContractSerializer cs = new ContractSerializer(containingModule);
       cs.Visit(e);
       string val = cs.SerializedContract;
       args.Add(new Literal(val, SystemTypes.String));
     }
   }
   if (sc.SourceText != null) {
     args.Add(new NamedArgument(Identifier.For("Filename"), new Literal(sc.Document.Name, SystemTypes.String)));
     args.Add(new NamedArgument(Identifier.For("StartLine"), new Literal(sc.StartLine, SystemTypes.Int32)));
     args.Add(new NamedArgument(Identifier.For("StartColumn"), new Literal(sc.StartColumn, SystemTypes.Int32)));
     args.Add(new NamedArgument(Identifier.For("EndLine"), new Literal(sc.EndLine, SystemTypes.Int32)));
     args.Add(new NamedArgument(Identifier.For("EndColumn"), new Literal(sc.EndColumn, SystemTypes.Int32)));
     args.Add(new NamedArgument(Identifier.For("SourceText"), new Literal(sc.SourceText, SystemTypes.String)));
   }
   return new AttributeNode(attrBinding, args, (AttributeTargets)0);
 }    
Example #36
0
 protected override MemberBinding VisitBinding(MemberBinding binding)
 {
     this.Hash(binding.BindingType).Hash(binding.Member);
     return(base.VisitBinding(binding));
 }
Example #37
0
		public virtual void VisitMemberBinding (MemberBinding node)
		{
			if (node == null)
				return;

			VisitExpression (node.TargetObject);
		}
    public virtual Differences VisitMemberBinding(MemberBinding memberBinding1, MemberBinding memberBinding2){
      Differences differences = new Differences(memberBinding1, memberBinding2);
      if (memberBinding1 == null || memberBinding2 == null){
        if (memberBinding1 != memberBinding2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++;
        return differences;
      }
      MemberBinding changes = (MemberBinding)memberBinding2.Clone();
      MemberBinding deletions = (MemberBinding)memberBinding2.Clone();
      MemberBinding insertions = (MemberBinding)memberBinding2.Clone();

      if (memberBinding1.Alignment == memberBinding2.Alignment) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++;

      Differences diff = this.VisitMember(memberBinding1.BoundMember, memberBinding2.BoundMember);
      if (diff == null){Debug.Assert(false); return differences;}
      changes.BoundMember = diff.Changes as Member;
      deletions.BoundMember = diff.Deletions as Member;
      insertions.BoundMember = diff.Insertions as Member;
      Debug.Assert(diff.Changes == changes.BoundMember && diff.Deletions == deletions.BoundMember && diff.Insertions == insertions.BoundMember);
      differences.NumberOfDifferences += diff.NumberOfDifferences;
      differences.NumberOfSimilarities += diff.NumberOfSimilarities;

      diff = this.VisitExpression(memberBinding1.TargetObject, memberBinding2.TargetObject);
      if (diff == null){Debug.Assert(false); return differences;}
      changes.TargetObject = diff.Changes as Expression;
      deletions.TargetObject = diff.Deletions as Expression;
      insertions.TargetObject = diff.Insertions as Expression;
      Debug.Assert(diff.Changes == changes.TargetObject && diff.Deletions == deletions.TargetObject && diff.Insertions == insertions.TargetObject);
      differences.NumberOfDifferences += diff.NumberOfDifferences;
      differences.NumberOfSimilarities += diff.NumberOfSimilarities;

      if (memberBinding1.Volatile == memberBinding2.Volatile) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++;

      if (differences.NumberOfDifferences == 0){
        differences.Changes = null;
        differences.Deletions = null;
        differences.Insertions = null;
      }else{
        differences.Changes = changes;
        differences.Deletions = deletions;
        differences.Insertions = insertions;
      }
      return differences;
    }
Example #39
0
 public override Expression VisitMemberBinding(MemberBinding memberBinding){
   if (memberBinding == null) return null;
   Expression tObj = memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject);
   Member mem = this.VisitMemberReference(memberBinding.BoundMember);
   if (mem == this.dummyMethod)
     mem = this.methodBeingSpecialized;
   Debug.Assert(mem != null);
   memberBinding.BoundMember = mem;
   if (memberBinding == null) return null;
   Method method = memberBinding.BoundMember as Method;
   if (method != null){
     //Need to take the address of the target object (this parameter), or need to box it, if this target object type is value type
     if (tObj != null && tObj.Type != null && tObj.Type.IsValueType){
       if (tObj.NodeType != NodeType.This){ 
         if (method.DeclaringType != null && method.DeclaringType.IsValueType) //it expects the address of the value type
           memberBinding.TargetObject = new UnaryExpression(memberBinding.TargetObject, NodeType.AddressOf, memberBinding.TargetObject.Type.GetReferenceType());
         else{ //it expects a boxed copy of the value type
           MemberBinding obType = new MemberBinding(null, memberBinding.TargetObject.Type);
           memberBinding.TargetObject = new BinaryExpression(memberBinding.TargetObject, obType, NodeType.Box, method.DeclaringType);
         }
       }else{
         //REVIEW: perhaps This nodes of value types should be explicitly typed as reference types
         //TODO: assert false in that case
       }
     }
   }
   TypeNode t = memberBinding.BoundMember as TypeNode;
   if (t != null) {
     TypeNode t1 = this.VisitTypeReference(t);
     memberBinding.BoundMember = t1;
   }
   return memberBinding;
 }
 private void EmitBinding(MemberBinding binding, Type objectType)
 {
     switch (binding.BindingType)
     {
         case MemberBindingType.Assignment:
             EmitMemberAssignment((MemberAssignment)binding, objectType);
             break;
         case MemberBindingType.ListBinding:
             EmitMemberListBinding((MemberListBinding)binding);
             break;
         case MemberBindingType.MemberBinding:
             EmitMemberMemberBinding((MemberMemberBinding)binding);
             break;
         default:
             throw Error.UnknownBindingType();
     }
 }
Example #41
0
 public virtual Expression VisitMemberBinding(MemberBinding memberBinding){
   if (memberBinding == null) return null;
   memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject);
   return memberBinding;
 }
Example #42
0
        public Func <EtwNativeEvent, object> GetTransform(Type outputType)
        {
            Expression <Func <EtwNativeEvent, SystemEvent> > template = e =>
                                                                        new SystemEvent
            {
                Header = new SystemHeader
                {
                    Timestamp         = e.TimeStamp.DateTime,
                    ActivityId        = e.ActivityId,
                    RelatedActivityId =
                        GetRelatedActivityId(
                            e.ExtendedDataCount,
                            e.ExtendedData, e.Flags),
                    PmcCounters =
                        GetPmcCounters(
                            e.ExtendedDataCount,
                            e.ExtendedData),
                    ProviderId  = e.ProviderId,
                    EventId     = e.Id,
                    Opcode      = e.Opcode,
                    Version     = e.Version,
                    ProcessId   = e.ProcessId,
                    ProcessorId = e.ProcessorId,
                    ThreadId    = e.ThreadId,
                    Level       = e.Level,
                    Channel     = e.Channel,
                    Task        = e.Task,
                    Keywords    = e.Keyword,
                }
            };

            if (outputType == typeof(SystemEvent))
            {
                return(template.Compile());
            }

            LambdaExpression ex = template;
            var mi       = (MemberInitExpression)ex.Body;
            var bindings = new List <MemberBinding>(mi.Bindings);
            ParameterExpression reader = ex.Parameters[0];

            PropertyInfo[] properties = outputType.GetProperties();
            foreach (PropertyInfo p in properties)
            {
                var attribute = p.GetAttribute <EventFieldAttribute>();
                if (attribute == null)
                {
                    continue;
                }

                Expression readExpression = null;


                switch (attribute.OriginalType)
                {
                case "win:Boolean":
                    readExpression = MakeExpression(r => r.ReadBoolean(), reader);
                    break;

                case "win:Pointer":
                    readExpression = MakeExpression(r => r.ReadPointer(), reader);
                    break;

                case "win:Int8":
                    readExpression = MakeExpression(r => r.ReadInt8(), reader);
                    break;

                case "win:UInt8":
                    readExpression = MakeExpression(r => r.ReadUInt8(), reader);
                    break;

                case "win:Int16":
                    readExpression = MakeExpression(r => r.ReadInt16(), reader);
                    break;

                case "win:UInt16":
                    readExpression = MakeExpression(r => r.ReadUInt16(), reader);
                    break;

                case "win:Int32":
                    readExpression = MakeExpression(r => r.ReadInt32(), reader);
                    break;

                case "win:HexInt32":
                case "win:UInt32":
                    readExpression = MakeExpression(r => r.ReadUInt32(), reader);
                    break;

                case "win:Int64":
                    readExpression = MakeExpression(r => r.ReadInt64(), reader);
                    break;

                case "win:HexInt64":
                case "win:UInt64":
                    readExpression = MakeExpression(r => r.ReadUInt64(), reader);
                    break;

                case "win:Double":
                    readExpression = MakeExpression(r => r.ReadDouble(), reader);
                    break;

                case "win:Float":
                    readExpression = MakeExpression(r => r.ReadFloat(), reader);
                    break;

                case "win:UnicodeString":
                    if (!String.IsNullOrEmpty(attribute.Length))
                    {
                        int len = 0;
                        if (int.TryParse(attribute.Length, out len))
                        {
                            readExpression = MakeExpression(r => r.ReadUnicodeString(len), reader);
                        }
                        else
                        {
                            readExpression = MakeExpression(r => r.ReadUnicodeStringPrefixLen(), reader);
                        }
                    }
                    else
                    {
                        readExpression = MakeExpression(r => r.ReadUnicodeString(), reader);
                    }
                    break;

                case "win:AnsiString":
                    if (!String.IsNullOrEmpty(attribute.Length))
                    {
                        int len = 0;
                        if (int.TryParse(attribute.Length, out len))
                        {
                            readExpression = MakeExpression(r => r.ReadAnsiString(len), reader);
                        }
                        else
                        {
                            readExpression = MakeExpression(r => r.ReadAnsiStringPrefixLen(), reader);
                        }
                    }
                    else
                    {
                        readExpression = MakeExpression(r => r.ReadAnsiString(), reader);
                    }
                    break;

                case "win:FILETIME":
                    readExpression = MakeExpression(r => r.ReadFileTime(), reader);
                    break;

                case "win:SYSTEMTIME":
                    readExpression = MakeExpression(r => r.ReadSystemTime(), reader);
                    break;

                case "win:SID":
                    readExpression = MakeExpression(r => r.ReadSid(), reader);
                    break;

                case "win:Binary":
                    // HACK: this is not handling the length
                    readExpression = MakeExpression(r => r.ReadBytes(), reader);
                    break;

                case "win:GUID":
                    readExpression = MakeExpression(r => r.ReadGuid(), reader);
                    break;

                default:
                    throw new NotImplementedException("Unknown primitive type " + attribute.OriginalType);
                }

                // the following is to handle value maps, that were emitted as enumerations
                if (p.PropertyType.IsEnum)
                {
                    readExpression = Expression.Convert(readExpression, p.PropertyType);
                }

                MemberBinding b = Expression.Bind(p, readExpression);
                bindings.Add(b);
            }

            NewExpression        n    = Expression.New(outputType);
            MemberInitExpression m    = Expression.MemberInit(n, bindings.ToArray());
            UnaryExpression      cast = Expression.Convert(m, typeof(object));
            Expression <Func <EtwNativeEvent, object> > exp = Expression.Lambda <Func <EtwNativeEvent, object> >(cast,
                                                                                                                 ex.Parameters);

            return(exp.Compile());
        }
			public override Expression VisitMemberBinding (MemberBinding memberBinding)
			{
				Inspect(memberBinding.Type, memberBinding);
				return base.VisitMemberBinding(memberBinding);
			}
 protected override void VisitBinding(MemberBinding binding)
 {
     CannotOptimize(binding);
 }
Example #45
0
 public virtual Expression VisitMemberBinding(MemberBinding memberBinding, MemberBinding changes, MemberBinding deletions, MemberBinding insertions){
   this.UpdateSourceContext(memberBinding, changes);
   if (memberBinding == null) return changes;
   if (changes != null){
     if (deletions == null || insertions == null)
       Debug.Assert(false);
     else{
     }
   }else if (deletions != null)
     return null;
   return memberBinding;
 }
Example #46
0
 private Field NewField(Identifier name, TypeNode type, Anonymity anon){
   AttributeList attrs = null;
   if (anon != Anonymity.Unknown && anon != Anonymity.None){
     attrs = new AttributeList(1);
     MemberBinding cons = new MemberBinding(null, SystemTypes.AnonymousAttribute.GetConstructor());
     TypeNode tn = SystemTypes.AnonymityEnum;
     AttributeNode attr = new AttributeNode(cons, new ExpressionList(new NamedArgument(idAnonymity, new Literal(anon, SystemTypes.AnonymityEnum))));
     attrs.Add(attr);
   }
   return new Field(null, attrs, FieldFlags.Public, name, type, null);
 }
Example #47
0
 public virtual void GetProjectionList(Accessor accessor, Expression source, ExpressionList list){
   if (accessor == null) return;
   MemberAccessor ma = accessor as MemberAccessor;
   if (ma != null){
     MemberBinding mb = new MemberBinding(source, ma.Member);
     mb.SourceContext = source.SourceContext;
     if (ma.Yield){
       list.Add(mb);
     }
     if (ma.Next != null){
       this.GetProjectionList(ma.Next, mb, list);
     }
     return;
   }
   SequenceAccessor sa = accessor as SequenceAccessor;
   if (sa != null){
     foreach( Accessor acc in sa.Accessors ){
       this.GetProjectionList(acc, source, list);
     }
     return;
   }
   this.HandleError(source, Error.QueryProjectThroughTypeUnion);
 }
 static int CountBindingExprs(MemberBinding binding)
 => binding switch
 {