public override Expression CoerceAnonymousNestedFunction(AnonymousNestedFunction func, TypeNode targetType, bool explicitCoercion, TypeViewer typeViewer) { if (func is AnonymousNestedDelegate && !(targetType is DelegateNode)) { this.HandleError(func, Error.AnonMethToNonDel, this.GetTypeName(targetType)); return(null); } return(base.CoerceAnonymousNestedFunction(func, targetType, explicitCoercion, typeViewer)); }
// TODO: Remove this? There shouldn't be any ANFs that need to be serialized in a contract public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction anf) { // we can serialize an ANF only if it is really just a wrapper around a comprehension // in that case, just serialize the comprehension and let the deserializer // reconstruct the ANF. if (anf == null) { return(null); } if (anf.Body == null) { return(anf); } if (anf.Body.Statements == null) { return(anf); } if (anf.Body.Statements.Count != 1) { return(anf); } ExpressionStatement es = anf.Body.Statements[0] as ExpressionStatement; if (es == null) { return(anf); } Comprehension q = es.Expression as Comprehension; if (q == null) { return(anf); } this.VisitComprehension(q); return(anf); }
public virtual Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func, AnonymousNestedFunction changes, AnonymousNestedFunction deletions, AnonymousNestedFunction insertions){ this.UpdateSourceContext(func, changes); if (func == null) return changes; if (changes != null){ if (deletions == null || insertions == null) Debug.Assert(false); else{ func.Body = this.VisitBlock(func.Body, changes.Body, deletions.Body, insertions.Body); func.Parameters = this.VisitParameterList(func.Parameters, changes.Parameters, deletions.Parameters, insertions.Parameters); } }else if (deletions != null) return null; return func; }
public virtual Differences VisitAnonymousNestedFunction(AnonymousNestedFunction/*!*/ func1, AnonymousNestedFunction func2) { Differences differences = new Differences(func1, func2); if (func1 == null || func2 == null){ if (func1 != func2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } AnonymousNestedFunction changes = (AnonymousNestedFunction)func2.Clone(); AnonymousNestedFunction deletions = (AnonymousNestedFunction)func2.Clone(); AnonymousNestedFunction insertions = (AnonymousNestedFunction)func2.Clone(); Differences diff = this.VisitBlock(func1.Body, func2.Body); if (diff == null){Debug.Assert(false); return differences;} changes.Body = diff.Changes as Block; deletions.Body = diff.Deletions as Block; insertions.Body = diff.Insertions as Block; Debug.Assert(diff.Changes == changes.Body && diff.Deletions == deletions.Body && diff.Insertions == insertions.Body); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; ParameterList parChanges, parDeletions, parInsertions; diff = this.VisitParameterList(func1.Parameters, func2.Parameters, out parChanges, out parDeletions, out parInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.Parameters = parChanges; deletions.Parameters = parDeletions; insertions.Parameters = parInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; 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 virtual Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func){ if (func == null) return null; func.Parameters = this.VisitParameterList(func.Parameters); func.Body = this.VisitBlock(func.Body); return func; }
public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func) { if (func == null) return null; func.Method = this.VisitMethod(func.Method); return func; }
public virtual void FillInImplicitType(AnonymousNestedFunction anonFunc, DelegateNode delegateNode) { if (anonFunc == null || delegateNode == null) return; ParameterList afParams = anonFunc.Parameters; ParameterList delParams = delegateNode.Parameters; if (afParams == null || delParams == null || afParams.Count != delParams.Count) return; for (int i = 0, n = afParams.Count; i < n; i++) { Parameter p = afParams[i]; if (p == null || p.Type != null) continue; Parameter q = delParams[i]; if (q != null) p.Type = q.Type; } }
public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func){ if (func == null) return null; Method meth = func.Method = this.VisitMethod(func.Method); if (meth == null || meth.DeclaringType == null) return null; if (meth.Scope != null) { meth.Scope.ThisTypeInstance = meth.DeclaringType; #if WHIDBEY if (meth.DeclaringType is ClosureClass) { TypeNodeList tpars = meth.DeclaringType.ConsolidatedTemplateParameters; if (tpars != null && tpars.Count > 0) { //Create a "fake" dummy instance. Using the real template instantiation code will not work //because the closure class has not yet been added to the members of its declaring type. TypeNode tinst = (TypeNode)meth.DeclaringType.Clone(); tinst.Template = meth.DeclaringType; meth.Scope.ThisTypeInstance = tinst; } } #endif } if (meth.ReturnType == null){ //No return type inferred for function. This happens when no return or yield were encountered, or when no return has a value. this.InferReturnTypeForExpressionFunction(meth); } func.Type = FunctionType.For(meth.ReturnType, meth.Parameters, this.currentType); //TODO: find all places where control leaves the function after an expression statement and insert return statements return func; }
public virtual void VisitAnonymousNestedFunction(AnonymousNestedFunction func) { if (func == null) return; this.VisitParameterList(func.Parameters); this.VisitBlock(func.Body); }
public virtual Expression CoerceAnonymousNestedFunction(AnonymousNestedFunction func, TypeNode targetType, bool explicitCoercion, TypeViewer typeViewer) { if (func.Invocation != null){ Debug.Assert(!explicitCoercion); if (func.Type != targetType && this.ImplicitCoercionFromTo(func.Invocation.Type, targetType)){ func.Type = targetType; func.Invocation = this.ImplicitCoercion(func.Invocation, targetType, typeViewer); } return func; } DelegateNode targetDType = targetType as DelegateNode; if (targetDType != null) { //TODO: if func is nested in a generic method and delegate is generic instance Method meth = func.Method; if (meth == null) return null; //We wrap each return expression of the anonymous method with an implicit //coercion if (TypeNode.StripModifiers(meth.ReturnType) != TypeNode.StripModifiers(targetDType.ReturnType)) { if (this.ImplicitCoercionFromTo(meth.ReturnType, targetDType.ReturnType)) { func.Type = targetType; meth.ReturnType = targetDType.ReturnType; meth.Body = ImplicitCoercionReturnExp(meth.Body, targetDType.ReturnType); } else { this.HandleError(func, Error.NestedFunctionDelegateReturnTypeMismatch, this.GetTypeName(targetDType)); return func; } } if (func.Parameters == null && targetDType.Parameters != null) { ParameterList parameters = meth.Parameters = targetDType.Parameters.Clone(); for (int i = 0, n = parameters.Count; i < n; i++) { Parameter par = parameters[i]; if (par == null) continue; if (par.IsOut || (par.Type != null && par.Type is Reference)) { this.HandleError(func, Error.NestedFunctionDelegateParameterMismatchBecauseOfOutParameter, this.GetTypeName(targetDType)); return func; } parameters[i] = par = (Parameter)par.Clone(); par.DeclaringMethod = meth; } } else { ParameterList savedMethodParams = meth.Parameters; meth.Parameters = func.Parameters; if (!meth.ParametersMatch(targetDType.Parameters)) { this.HandleError(func, Error.NestedFunctionDelegateParameterMismatch, this.GetTypeName(targetDType)); return func; } meth.Parameters = savedMethodParams; } InstanceInitializer dcons = TypeViewer.GetTypeView(typeViewer, targetType).GetConstructor(SystemTypes.Object, SystemTypes.IntPtr); if (dcons == null) return func; MemberBinding memb = new MemberBinding(null, meth); memb.Type = null; Expression ldftn = new UnaryExpression(memb, NodeType.Ldftn); ldftn.Type = SystemTypes.IntPtr; ExpressionList arguments = new ExpressionList(2); if (meth.IsStatic) arguments.Add(Literal.Null); else arguments.Add(new CurrentClosure(meth, meth.DeclaringType)); arguments.Add(ldftn); Construct cons = new Construct(new MemberBinding(null, dcons), arguments, targetType); cons.SourceContext = func.SourceContext; func.Invocation = cons; func.Type = targetType; return func; } else { Method invoker = func.Method; if (invoker != null && (invoker.Parameters == null || invoker.Parameters.Count == 0)) { Expression ob = invoker.IsStatic ? null : new CurrentClosure(invoker, invoker.DeclaringType); Expression call = new MethodCall(new MemberBinding(ob, invoker), null, NodeType.Call, invoker.ReturnType, func.SourceContext); if (explicitCoercion) func.Invocation = this.ExplicitCoercion(call, targetType, typeViewer); else func.Invocation = this.ImplicitCoercion(call, targetType, typeViewer); func.Type = targetType; } else { func.Invocation = null; Error e = explicitCoercion ? Error.NoExplicitCoercion : Error.NoImplicitCoercion; FunctionType ftype = FunctionType.For(func.Method.ReturnType, func.Method.Parameters, this.currentType); Node n = new Expression(NodeType.Nop); n.SourceContext = invoker.Parameters[0].SourceContext; n.SourceContext.EndPos = func.Body.SourceContext.EndPos; this.HandleError(n, e, this.GetMemberSignature(ftype), this.GetTypeName(targetType)); } return func; } }
// TODO: Remove this? There shouldn't be any ANFs that need to be serialized in a contract public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction anf) { // we can serialize an ANF only if it is really just a wrapper around a comprehension // in that case, just serialize the comprehension and let the deserializer // reconstruct the ANF. if (anf == null) return null; if (anf.Body == null) return anf; if (anf.Body.Statements == null) return anf; if (anf.Body.Statements.Count != 1) return anf; ExpressionStatement es = anf.Body.Statements[0] as ExpressionStatement; if (es == null) return anf; Comprehension q = es.Expression as Comprehension; if (q == null) return anf; this.VisitComprehension(q); return anf; }
public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func) { if (func == null) return null; AnonymousNestedFunction dup = (AnonymousNestedFunction)func.Clone(); if (func.Method != null) { dup.Method = this.VisitMethod(func.Method); //^ assume dup.Method != null; dup.Parameters = dup.Method.Parameters; dup.Body = dup.Method.Body; return dup; } return base.VisitAnonymousNestedFunction(dup); }
public virtual Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func1, AnonymousNestedFunction func2) { if (func1 == null) return null; if (func2 == null) { func1.Parameters = this.VisitParameterList(func1.Parameters, null); func1.Body = this.VisitBlock(func1.Body, null); } else { func1.Parameters = this.VisitParameterList(func1.Parameters, func2.Parameters); func1.Body = this.VisitBlock(func1.Body, func2.Body); } return func1; }
public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func){ if (func == null) return null; Method method = func.Method; if (method == null) return null; TypeNode[] parameterTypes = null; if (this.currentMethod != null && this.currentMethod.Scope != null) { int paramCount = method.Parameters == null ? 0 : method.Parameters.Count; parameterTypes = new TypeNode[paramCount]; method.ReturnType = this.currentMethod.Scope.FixTypeReference(method.ReturnType); for (int i = 0; i < paramCount; i++) { Parameter p = method.Parameters[i]; if (p == null) continue; p.Type = this.currentMethod.Scope.FixTypeReference(p.Type); parameterTypes[i] = p.Type; } } Block block = method.Body; StatementList statements = block == null ? null : block.Statements; if (statements != null && statements.Count == 2 && statements[0] is ExpressionStatement && statements[1] is Return){ statements[0].SourceContext.Document = null; if (method.Attributes == null) method.Attributes = new AttributeList(2); method.Attributes.Add(new AttributeNode(new MemberBinding(null, SystemTypes.DebuggerHiddenAttribute.GetConstructor()), null)); method.Attributes.Add(new AttributeNode(new MemberBinding(null, SystemTypes.DebuggerStepThroughAttribute.GetConstructor()), null)); } this.VisitMethod(method); method.DeclaringType.Members.Add(method); if (this.currentClosureLocal != null && this.currentClosureLocal.Type != null && this.currentClosureLocal.Type.Template != null) { Construct cons = func.Invocation as Construct; if (cons != null && cons.Operands != null && cons.Operands.Count >= 2) { UnaryExpression ue = cons.Operands[1] as UnaryExpression; if (ue != null) { MemberBinding mb = ue.Operand as MemberBinding; if (mb != null && mb.BoundMember == method) { Method specializedMethod = (Method)mb.BoundMember.Clone(); specializedMethod.Parameters = specializedMethod.Parameters.Clone(); for (int i = 0, n = specializedMethod.Parameters.Count; i < n; i++) { Parameter p = (Parameter)specializedMethod.Parameters[i].Clone(); p.DeclaringMethod = specializedMethod; specializedMethod.Parameters[i] = p; } mb.BoundMember = specializedMethod; specializedMethod.DeclaringType = this.currentClosureLocal.Type; this.currentClosureLocal.Type.Members.Add(specializedMethod); } } } } return this.VisitExpression(func.Invocation); }
public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func){ return func; }
public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func){ if (func == null) return null; if (!(this.scope is BlockScope || this.scope is MethodScope)){ this.HandleError(func, Error.AnonymousNestedFunctionNotAllowed); return null; } Method method = func.Method = new Method(); method.Name = Identifier.For("Function:"+func.UniqueKey); this.ConstructMethodForNestedFunction(func, func.Method, null, func.Parameters, func.Body); return func; }