Ejemplo n.º 1
0
 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));
 }
Ejemplo n.º 2
0
        // 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);
        }
Ejemplo n.º 3
0
 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;
 }
Ejemplo n.º 4
0
    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;
    }
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
 public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func) {
   if (func == null) return null;
   func.Method = this.VisitMethod(func.Method);
   return func;
 }
Ejemplo n.º 7
0
 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;
   }
 }
Ejemplo n.º 8
0
    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;
    }
Ejemplo n.º 9
0
 public virtual void VisitAnonymousNestedFunction(AnonymousNestedFunction func)
 {
   if (func == null) return;
   this.VisitParameterList(func.Parameters);
   this.VisitBlock(func.Body);
 }
Ejemplo n.º 10
0
 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;
   }
 }
Ejemplo n.º 11
0
 // 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;
 }
Ejemplo n.º 12
0
 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);
 }
Ejemplo n.º 13
0
 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;
 }
Ejemplo n.º 14
0
 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);
 }
Ejemplo n.º 15
0
 public override Expression VisitAnonymousNestedFunction(AnonymousNestedFunction func){
   return func;
 }
Ejemplo n.º 16
0
 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;
 }