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); }
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; }
//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; }
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); } } }
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; }
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; }
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("="); }
protected abstract void WriteBinding(MemberBinding binding);
/// <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()); }
/// <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); }
protected BindingRewriter(MemberBinding memberBinding, StackSpiller stackSpiller) { MemberBinding = memberBinding; StackSpiller = stackSpiller; }
protected override MemberBinding VisitMemberBinding(MemberBinding node) { _currentField = _target.StartBinding(node.Member); return(base.VisitMemberBinding(node)); }
protected override MemberBinding VisitMemberBinding(MemberBinding node) { return(this.GiveUp(node)); }
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)); }
public virtual Expression OnInvalidMemberBinding(MemberBinding mb, QualifiedIdentifier qualId){ return mb; }
public int GetHashCode(MemberBinding binding) { return(this.hash.GetHashCode(binding)); }
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()); }
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)); }
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; }
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; }
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; }
public virtual Expression VisitMemberBinding (MemberBinding node) { if (node == null) return null; node.TargetObject = VisitExpression (node.TargetObject); return node; }
/// <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 && sc != null; /// </code></para> /// <para><code> /// requires ctor.DeclaringType <: 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); }
protected override MemberBinding VisitBinding(MemberBinding binding) { this.Hash(binding.BindingType).Hash(binding.Member); return(base.VisitBinding(binding)); }
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; }
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(); } }
public virtual Expression VisitMemberBinding(MemberBinding memberBinding){ if (memberBinding == null) return null; memberBinding.TargetObject = this.VisitExpression(memberBinding.TargetObject); return memberBinding; }
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); }
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; }
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); }
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 {