public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure, CurrentClosure changes, CurrentClosure deletions, CurrentClosure insertions){ this.UpdateSourceContext(currentClosure, changes); if (currentClosure == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ } }else if (deletions != null) return null; return currentClosure; }
public virtual Expression VisitCurrentClosure(CurrentClosure currentClosure){ return currentClosure; }
public virtual Differences VisitCurrentClosure(CurrentClosure currentClosure1, CurrentClosure currentClosure2){ Differences differences = new Differences(currentClosure1, currentClosure2); if (currentClosure1 == null || currentClosure2 == null){ if (currentClosure1 != currentClosure2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; }else{ differences.NumberOfSimilarities++; differences.Changes = null; } return differences; }
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 VisitMethodCall(MethodCall call) { if (call == null) return null; NameBinding nb = call.Callee as NameBinding; if (nb != null) { if (nb.Identifier != Looker.NotFound) { this.VisitNameBinding(nb); //Reports the error return null; } int numPars = call.Operands == null ? 0 : call.Operands.Count; bool callOperandsAlreadyNull = (call.Operands == null); ExpressionList operands = call.Operands = this.VisitExpressionList(call.Operands); if (operands == null && !callOperandsAlreadyNull || operands != null && operands.Count != numPars) return null; for (int i = 0; i < numPars; i++) if (call.Operands[i] == null) return null; //The error could have been caused by the bad argument. bool hasArglist = false; int arglistIndex = -1; for (int i = 0; i < numPars; i++) { if (call.Operands[i] is ArglistArgumentExpression) { hasArglist = true; arglistIndex = i; break; } } MemberList members = nb.BoundMembers; int n = members == null ? 0 : members.Count; MethodList ambiguousMethods = new MethodList(n); Method inaccessibleMethod = null; Method templateMethodWithFailedInference = null; Method objectMatchArglistMethod = null; for (int i = 0; i < n; i++) { Method meth = members[i] as Method; if (meth == null) continue; if ((meth.Parameters == null ? 0 : meth.Parameters.Count) != numPars) continue; if (this.NotAccessible(meth)) { inaccessibleMethod = meth; continue; } else { string mname = meth.Name != null ? meth.Name.ToString() : ""; if (this.insideMethodContract || this.insideInvariant) { if (!this.AsAccessible(meth, currentMethod) && !this.insideInvariant) { this.HandleError(meth, Error.MemberNotVisible, this.GetTypeName(meth.DeclaringType)+"."+mname); // WS better error message return null; } if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(meth, currentMethod)) { this.HandleError(meth, Error.MemberMustBePureForMethodContract, this.GetTypeName(meth.DeclaringType)+"."+mname); return null; } if (this.insideInvariant && !this.IsTransparentForInvariant(meth, currentMethod)) { this.HandleError(meth, Error.MemberMustBePureForInvariant, this.GetTypeName(meth.DeclaringType)+"."+mname); return null; } } else if (!this.IsModelUseOk(meth, currentMethod)) { this.HandleError(meth, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(meth.DeclaringType)+"."+mname); return null; } } if (meth.TemplateParameters != null && meth.TemplateParameters.Count > 0) { templateMethodWithFailedInference = meth; continue; } if (hasArglist && arglistIndex < meth.Parameters.Count && meth.Parameters[arglistIndex].Type == SystemTypes.Object) { objectMatchArglistMethod = meth; } ambiguousMethods.Add(meth); } if (ambiguousMethods.Count >= 2) { this.HandleError(call, Error.AmbiguousCall, this.GetMethodSignature(ambiguousMethods[0]), this.GetMethodSignature(ambiguousMethods[1])); return null; } if (inaccessibleMethod != null) { this.HandleError(call, Error.MemberNotVisible, this.GetMethodSignature(inaccessibleMethod)); return null; } if (templateMethodWithFailedInference != null) { this.HandleError(call, Error.CannotInferMethTypeArgs, this.GetMethodSignature(templateMethodWithFailedInference)); return null; } if (objectMatchArglistMethod != null) { this.HandleError(call, Error.CannotMatchArglist, objectMatchArglistMethod.Name.Name); this.HandleRelatedError(objectMatchArglistMethod); return null; } Identifier id = null; for (int i = 0; i < n; i++) { Member mem = members[i]; if (!(mem is Method)) continue; if (id == null && mem.Name != null) { id = mem.Name; string name = id.Name; if (mem is InstanceInitializer && mem.DeclaringType != null && mem.DeclaringType.Name != null) name = mem.DeclaringType.Name.Name; else if (mem.IsSpecialName) name = this.GetMemberName(mem); this.HandleError(nb, Error.NoOverloadWithMatchingArgumentCount, name, (call.Operands == null ? 0 : call.Operands.Count).ToString()); } this.HandleRelatedError(mem); } return null; } MemberBinding mb = call.Callee as MemberBinding; if (mb == null) { Expression e = this.VisitExpression(call.Callee); if (e != null) { if (e is Literal && e.Type == SystemTypes.Type) this.HandleError(e, Error.TypeInBadContext, this.GetTypeName((TypeNode)((Literal)e).Value)); else { TemplateInstance templInst = e as TemplateInstance; if (templInst != null) { if (templInst.Expression == null || templInst.TypeArguments == null) return null; this.VisitExpression(templInst.Expression); return null; } //HS D if (call.Callee is Hole) return null; this.HandleError(e, Error.NoSuchMethod); } } return null; } Method method = mb.BoundMember as Method; if (method == null) { if (mb.BoundMember != null) { if (mb.BoundMember is Event) this.HandleError(mb, Error.BadCallToEventHandler, this.GetMemberSignature(mb.BoundMember)); else this.HandleNonMethodWhereMethodExpectedError(mb, mb.BoundMember); } return null; } bool initialMayReferenceThisAndBase = this.MayReferenceThisAndBase; if (mb.TargetObject is ImplicitThis || mb.TargetObject is This || mb.TargetObject is Base) { if (method is InstanceInitializer) { this.MayReferenceThisAndBase = true; //Base class constructor has been called } else if ((this.currentMethod == null && !this.insideModelfield // this is true when it is visited as part of a field initializer || !this.MayReferenceThisAndBase) // this is true when it is visited as part of a ctor with an explicit call to base in the body && !this.AllowThisTarget(method) && !this.insideInvariant) { if (mb.TargetObject is ImplicitThis) { this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method, true)); } else if (mb.TargetObject is Base) { this.HandleError(mb.TargetObject, Error.BaseInBadContext); } else { this.HandleError(mb.TargetObject, Error.ThisInBadContext); } return null; } } if (method == Resolver.IndexerNotFound) { if (mb.TargetObject == null) return null; if (this.TypeInVariableContext(mb.TargetObject as Literal)) return null; Expression tgtObj = this.VisitExpression(mb.TargetObject); if (tgtObj == null) return null; this.HandleError(tgtObj, Error.NotIndexable, this.GetTypeName(mb.TargetObject.Type)); return null; } if (method.Name == Looker.NotFound) { //TODO: report the error return null; } TypeNode obType = mb.TargetObject == null ? null : mb.TargetObject.Type; if (mb.TargetObject is Base) obType = this.currentType; obType = TypeNode.StripModifiers(obType); if (this.NotAccessible(method, ref obType)) { if (method.IsSpecialName && method.Parameters != null && method.Parameters.Count > 0 && method.Name.ToString().StartsWith("get_")) this.HandleError(call, Error.NotIndexable, this.GetTypeName(mb.TargetObject.Type)); else if (mb.TargetObject == null || mb.TargetObject.Type == null || this.NotAccessible(method)) this.HandleError(call, Error.MemberNotVisible, this.GetMethodSignature(method)); else this.HandleError(mb.BoundMemberExpression == null ? mb : mb.BoundMemberExpression, Error.NotVisibleViaBaseType, this.GetMethodSignature(method), this.GetTypeName(mb.TargetObject.Type), this.GetTypeName(this.currentType)); return null; } else { if (this.insideMethodContract || this.insideInvariant || this.insideAssertOrAssume) { string mname = method.Name == null ? "" : method.Name.ToString(); if (!this.AsAccessible(method, currentMethod) && !this.insideInvariant && !this.insideMethodContract && !this.insideAssertOrAssume) { this.HandleError(mb, Error.MemberNotVisible, this.GetTypeName(method.DeclaringType)+"."+mname); return null; } if ((this.insideMethodContract || this.insideAssertOrAssume) && !this.IsTransparentForMethodContract(method, currentMethod)) { this.HandleError(mb, Error.MemberMustBePureForMethodContract, this.GetTypeName(method.DeclaringType)+"."+mname); return null; } if (this.insideInvariant && !this.IsTransparentForInvariant(method, currentMethod)) { this.HandleError(mb, Error.MemberMustBePureForInvariant, this.GetTypeName(method.DeclaringType)+"."+mname); return null; } } else if (!this.IsModelUseOk(method, currentMethod)) { string mname = method.Name == null ? "" : method.Name.ToString(); this.HandleError(mb, Error.ModelMemberUseNotAllowedInContext, this.GetTypeName(method.DeclaringType)+"."+mname); return null; } } this.CheckDirectCallOfFinalize(method, call); if (method == this.currentMethod && method is InstanceInitializer) { this.HandleError(call, Error.RecursiveConstructorCall, this.GetMethodSignature(method)); return null; } if (method.IsStatic) { Expression targetOb = mb.TargetObject; if (targetOb != null) { MemberBinding memb = targetOb as MemberBinding; if (memb == null || memb.BoundMember == null || memb.Type == null || memb.Type.Name == null || memb.BoundMember.Name.UniqueIdKey != memb.Type.Name.UniqueIdKey) { MethodCall mcall = targetOb as MethodCall; memb = mcall == null ? null : mcall.Callee as MemberBinding; TypeNode mcallType = mcall == null ? null : TypeNode.StripModifiers(mcall.Type); if (memb == null || memb.BoundMember == null || !memb.BoundMember.IsSpecialName || mcallType == null || mcallType.Name == null || memb.BoundMember.Name.ToString() != "get_"+mcallType.Name.ToString()) { targetOb = this.VisitExpression(targetOb); if (targetOb != null) this.HandleError(targetOb, Error.TypeNameRequired, this.GetMethodSignature(method)); } } mb.TargetObject = targetOb = null; } } else { bool targetObIsNonNull = false; bool outerMayReferenceThisAndBase = this.MayReferenceThisAndBase; if (this.AllowThisTarget(method)) this.MayReferenceThisAndBase = true; Expression targetOb = mb.TargetObject = this.VisitExpression(mb.TargetObject); this.MayReferenceThisAndBase = outerMayReferenceThisAndBase; if (targetOb != null) targetObIsNonNull = this.typeSystem.IsNonNullType(targetOb.Type); if (targetOb is Literal && targetOb.Type == SystemTypes.Type) { this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method, true)); return null; } if (this.currentMethod != null && this.currentMethod.IsStatic) { if (targetOb is ImplicitThis || targetOb is This || targetOb is Base) { ImplicitThis ithis = targetOb as ImplicitThis; if (ithis != null) { bool callToNestedFunction = false; if (this.currentMethod.Scope.CapturedForClosure) { TypeNode t = this.currentMethod.Scope.ClosureClass; while (t != null && !callToNestedFunction) { callToNestedFunction = t == method.DeclaringType; t = t.BaseType; } } if (!callToNestedFunction) ithis = null; } if (ithis == null) { this.HandleError(mb, Error.ObjectRequired, this.GetMethodSignature(method)); return null; } targetOb = new CurrentClosure(this.currentMethod, this.currentMethod.DeclaringType); } } TypeNode tObType = method.DeclaringType; if (tObType == null) return null; if (tObType.TemplateParameters != null && tObType.Template == null) tObType = tObType.GetTemplateInstance(tObType, tObType.TemplateParameters); if ((method.CallingConvention & CallingConventionFlags.ExplicitThis) != 0) { if (method.Parameters == null || method.Parameters.Count < 1 || method.Parameters[0] == null) Debug.Assert(false); else tObType = method.Parameters[0].Type; } if (tObType != null) { if (targetOb == null) return null; if (tObType.IsValueType) { targetOb = this.ConvertValueTypeCallTarget(targetOb, method, tObType); if (targetOb == null) return null; mb.TargetObject = this.GetAddressOf(targetOb, tObType); } else if (targetOb is Base && this.currentType != null && this.currentType.IsValueType) { targetOb = new AddressDereference(targetOb, this.currentType); mb.TargetObject = new BinaryExpression(targetOb, new MemberBinding(null, this.currentType), NodeType.Box, tObType); } else { if (tObType != targetOb.Type && !(targetOb is CurrentClosure && tObType is ClosureClass) && !(targetOb is This || targetOb is ImplicitThis)) { if (this.useGenerics && targetOb.Type is ITypeParameter && method.IsVirtual) { call.Constraint = targetOb.Type; if (targetOb.NodeType == NodeType.Indexer) targetOb = mb.TargetObject = new UnaryExpression(targetOb, NodeType.ReadOnlyAddressOf, targetOb.Type.GetReferenceType()); else targetOb = mb.TargetObject = this.GetAddressOf(targetOb, targetOb.Type); } else { Reference refType = targetOb.Type as Reference; if (this.useGenerics && refType != null && refType.ElementType is ITypeParameter) call.Constraint = refType.ElementType; else targetOb = mb.TargetObject = this.typeSystem.ExplicitCoercion(targetOb, tObType, this.TypeViewer); } if (targetOb == null) return null; } else if (targetOb.Type != null && !this.GetTypeView(targetOb.Type).IsAssignableTo(tObType) && targetOb.Type.IsNestedIn(tObType)) { this.HandleError(mb, Error.AccessToNonStaticOuterMember, this.GetTypeName(tObType), this.GetTypeName(targetOb.Type)); return null; } } } } bool savedMayReferenceThisAndBase = this.MayReferenceThisAndBase; this.MayReferenceThisAndBase = initialMayReferenceThisAndBase; this.CoerceArguments(method.Parameters, ref call.Operands, this.DoNotVisitArguments(method), method.CallingConvention); this.MayReferenceThisAndBase = savedMayReferenceThisAndBase; this.CheckForObsolesence(call, method); if (call.GiveErrorIfSpecialNameMethod && method.IsSpecialName) { string mname = method.Name == null ? null : method.Name.Name; if (mname != null && (mname.StartsWith(".") || mname.StartsWith("get_") || mname.StartsWith("set_") || mname.StartsWith("add_") || mname.StartsWith("remove_"))) this.HandleError(call, Error.CannotCallSpecialMethod, this.GetMethodSignature(method)); } if (method.IsAbstract && call.NodeType != NodeType.Callvirt) { Debug.Assert(mb.TargetObject is Base); this.HandleError(call, Error.AbstractBaseCall, this.GetMethodSignature(method)); } if (mb != null) { if (method != null && method.Contract != null && method.Contract.Ensures != null) { // Look at any checked exceptions listed in m's contract and make sure they // are covered by the list of allowedExceptions for (int i = 0, n = method.Contract.Ensures.Count; i < n; i++) { EnsuresExceptional ee = method.Contract.Ensures[i] as EnsuresExceptional; if (ee == null) continue; TypeNode thrownType = ee.Type; if (thrownType == null) continue; if (!this.GetTypeView(thrownType).IsAssignableTo(SystemTypes.ICheckedException)) continue; int j = 0; int p = this.allowedExceptions.Count; while (j < p) { TypeNode t = this.allowedExceptions[j]; if (this.GetTypeView(thrownType).IsAssignableTo(t)) break; j++; } if (j == p) { // no allowed exception covers this one this.HandleError(call, Error.CheckedExceptionNotInThrowsClause, this.GetTypeName(thrownType), this.GetMethodSignature(this.currentMethod)); } } } } int numTemplArgs = method.TemplateArguments == null ? 0 : method.TemplateArguments.Count; if (method != null && numTemplArgs > 0) { // check instantiation constraints int len = method.Template.TemplateParameters == null ? 0 : method.Template.TemplateParameters.Count; if (numTemplArgs != len) { this.HandleError(call, Error.TemplateTypeRequiresArgs, this.GetMethodSignature(method.Template), len.ToString(), "method"); return call; } Specializer specializer = len == 0 ? null : new Specializer(method.DeclaringType.DeclaringModule, method.Template.TemplateParameters, method.TemplateArguments); if (specializer != null) specializer.CurrentType = this.currentType; for (int i=0; i < len; i++) { TypeNode formal = method.Template.TemplateParameters[i]; ITypeParameter formaltp = (ITypeParameter)formal; TypeNode actual = method.TemplateArguments[i]; if (formal == null || actual == null) continue; // make sure actual is assignable to base of formal and to each interface TypeNode fbaseType = specializer == null ? formal.BaseType : specializer.VisitTypeReference(formal.BaseType); if (fbaseType != null && ( ((formaltp.TypeParameterFlags & TypeParameterFlags.ReferenceTypeConstraint) == TypeParameterFlags.ReferenceTypeConstraint && !actual.IsObjectReferenceType) || ((formaltp.TypeParameterFlags & TypeParameterFlags.ValueTypeConstraint) == TypeParameterFlags.ValueTypeConstraint && !actual.IsValueType) || !this.typeSystem.AssignmentCompatible(TypeNode.StripModifiers(actual), fbaseType, this.TypeViewer))) { Node offNode = call.CalleeExpression is TemplateInstance ? (Node)((TemplateInstance)call.CalleeExpression).TypeArgumentExpressions[i] : (Node)call.CalleeExpression; this.HandleError(offNode, Error.TypeParameterNotCompatibleWithConstraint, this.GetTypeName(actual), this.GetTypeName(fbaseType), this.GetTypeName(formal), this.GetMethodSignature(method.Template)); return call; } InterfaceList formal_ifaces = this.GetTypeView(formal).Interfaces; if (formal_ifaces != null) { for (int j = 0, n = formal_ifaces.Count; j < n; j++) { TypeNode intf = specializer == null ? formal_ifaces[j] : specializer.VisitTypeReference(formal_ifaces[j]); intf = TypeNode.StripModifiers(intf); if (intf == null) continue; if (intf != SystemTypes.ITemplateParameter && !this.typeSystem.AssignmentCompatible(TypeNode.StripModifiers(actual), intf, this.TypeViewer)) { Node offNode = call.CalleeExpression is TemplateInstance ? (Node)((TemplateInstance)call.CalleeExpression).TypeArgumentExpressions[i] : (Node)call.CalleeExpression; this.HandleError(offNode, Error.TypeParameterNotCompatibleWithConstraint, this.GetTypeName(actual), this.GetTypeName(intf), this.GetTypeName(formal), this.GetMethodSignature(method.Template)); return call; } } } } this.CheckGenericMethodSpecialConstraints(method, call); } return call; }
public virtual void VisitCurrentClosure(CurrentClosure currentClosure) { }
public override Expression VisitCurrentClosure(CurrentClosure currentClosure) { if (currentClosure == null) return null; return base.VisitCurrentClosure((CurrentClosure)currentClosure.Clone()); }
public override Expression VisitCurrentClosure(CurrentClosure currentClosure){ if (currentClosure == null) return null; if (this.currentClosureLocal == null && this.currentThisParameter != null) return new ThisBinding(this.currentThisParameter, currentClosure.SourceContext); return this.currentClosureLocal; }
public virtual void EndCurrentClosure(CurrentClosure cc) { if (cc != null){ //TODO: factor out the code for constructing the closure class, so that this elaborate setup is not necessary Checker checker = new Checker(null, this.typeSystem, null, null, null); checker.currentType = this.typeSystem.currentType = this.currentType; checker.currentMethod = this.currentMethod; Block oldBody = cc.Method.Body; TypeNode yieldType = this.typeSystem.GetStreamElementType(cc.Type, this.TypeViewer); cc.Method.Body = new Block(new StatementList(new Yield(new Literal(null, yieldType)))); checker.VisitMethod(cc.Method); Return ret = cc.Method.Body.Statements[0] as Return; Debug.Assert(ret != null); if (ret != null) { ConstructIterator ci = ret.Expression as ConstructIterator; Debug.Assert(ci != null); if (ci != null) { ci.Body = oldBody; cc.Method.Body.Scope = oldBody.Scope; this.VisitMethod(cc.Method); } } } }
public virtual CurrentClosure BeginCurrentClosure(TypeNode yieldType, string name) { TypeNode returnType = SystemTypes.GenericIEnumerable.GetTemplateInstance(this.currentType, new TypeNodeList(yieldType)); Class closureClass = this.currentMethod.Scope.ClosureClassTemplateInstance; Method method = new Method(); method.Name = Identifier.For(name + ":" + method.UniqueKey); method.Flags = MethodFlags.CompilerControlled|MethodFlags.Assembly; method.CallingConvention = CallingConventionFlags.HasThis; method.InitLocals = true; method.DeclaringType = closureClass; method.Body = new Block(new StatementList()); method.Scope = new MethodScope(this.currentMethod.Scope, null, method); method.Body.Scope = new BlockScope(method.Scope, method.Body); method.ReturnType = returnType; closureClass.Members.Add(method); CurrentClosure cc = new CurrentClosure(method, returnType); return cc; }