/// <summary>
        /// Need to visit closures as well
        /// </summary>
        public override void VisitConstruct(Construct cons)
        {
            if (cons == null) return;
            if (cons.Operands == null) return;
            if (cons.Operands.Count < 2) return;

            if (cons.Type.IsDelegateType())
            {
                UnaryExpression ue = cons.Operands[1] as UnaryExpression;
                if (ue == null) goto JustVisit;

                MemberBinding mb = ue.Operand as MemberBinding;
                if (mb == null) goto JustVisit;
                
                Method m = mb.BoundMember as Method;
                
                var um = HelperMethods.Unspecialize(m);
                
                if (HelperMethods.IsAnonymousDelegate(um, this.CurrentType))
                {
                    this.VisitAnonymousDelegate(um, m);
                }
            }
        
            JustVisit:
            base.VisitConstruct(cons);
        }
        public override void VisitConstruct(Construct cons)
        {
            if ((cons.Type.IsDelegateType()))
            {
                UnaryExpression ue = cons.Operands[1] as UnaryExpression;
                if (ue != null)
                {
                    MemberBinding mb = ue.Operand as MemberBinding;
                    if (mb != null)
                    {
                        Method m = (Method) mb.BoundMember;
                        if (HelperMethods.IsClosureMethod(this.containingType, m))
                        {
                            if (HelperMethods.IsClosureType(this.containingType, m.DeclaringType))
                            {
                                // Roslyn-based compiler changed non-capturing lambda caching.
                                // Instead of storing delegate in a field like CS$<>9_CachedAnonymousMethodDelegate1
                                // Roslyn-based compiler generates a closure class called <>c with a set of instance
                                // methods and a singleton instance.
                                // This change allows to duplicate this new closure type
                                if (HelperMethods.IsRoslynBasedStaticClosure(m.DeclaringType))
                                {
                                    TryAddTypeToMembersToDuplicate(m.DeclaringType);
                                }
                            }
                            else
                            {
                                // Logic for pre-Roslyn compiler.

                                // then there is no closure class, m is just a method the compiler
                                // added to the class itself

                                // we record the instance here, although we will eventually make a copy of the
                                // template by making the method generic in its parent type type-parameters.
                                MembersToDuplicate.Add(m);
                            }
                        }
                        else
                        {
                            //Console.WriteLine("Not atomic closure part: {0}", m.FullName);
                            var declaringTypeName = m.DeclaringType.Name.Name;
                            var name = m.Name.Name;
                            string message =
                                String.Format(
                                    "DeclaringName should contain 'DisplayClass', <>c or Name should not have '__'. \r\nDeclaringTypeName: {0}, Name: {1}",
                                    declaringTypeName, name);

                            Debug.Assert(
                                declaringTypeName.Contains("DisplayClass") || declaringTypeName.Contains("<>c") ||
                                !name.Contains("__"), message);
                        }
                    }
                }
            }

            base.VisitConstruct(cons);
        }
Beispiel #3
0
    /// <summary>
    /// If there is an anonymous delegate within a postcondition, then there
    /// will be a call to a delegate constructor.
    /// That call looks like "d..ctor(o,m)" where d is the type of the delegate.
    /// There are two cases depending on whether the anonymous delegate captured
    /// anything. In both cases, m is the method implementing the anonymous delegate.
    /// 
    /// (1) It does capture something. Then o is the instance of the closure class
    /// implementing the delegate, and m is an instance method in the closure
    /// class.
    /// (2) It does *not* capture anything. Then o is the literal for null and
    /// m is a static method that was added directly to the class.
    /// 
    /// This method will cause m to be visited to collect any old expressions
    /// that occur in it. But those old expressions are not turned into locals,
    /// but fields. The fields are created as either (1) members of the closure class,
    /// or (2) members of the class in which the method containing the contract
    /// containing the Old expression is defined.
    /// The fields are initialized when (1) the closure class instance is created,
    /// or (2) ... ??? (when!?)
    /// So set up enough state so that when those old expressions are visited, the
    /// correct ASTs can be built.
    /// </summary>
    /// <param name="cons">The AST representing the call to the constructor
    /// of the delegate type.</param>
    /// <returns>Whatever the base visitor returns</returns>
    public override Expression VisitConstruct(Construct cons) {
      if (cons.Type is DelegateNode) {
        UnaryExpression ue = cons.Operands[1] as UnaryExpression;
        if (ue == null) goto JustVisit;
        MemberBinding mb = ue.Operand as MemberBinding;
        if (mb == null) goto JustVisit;
        Method m = mb.BoundMember as Method;

        Contract.Assume(m != null);

        if (m.IsStatic) {
          // then there is no closure class, m is just a static method the compiler
          // added to the class itself
          goto JustVisit;
        }
        if (HelperMethods.IsCompilerGenerated(m)) {
          Local l = cons.Operands[0] as Local;
          if (l == null) goto JustVisit; // but then what is it??
          TypeNode savedClosureClass = this.currentClosureClass;
          this.currentClosureClass = l.Type;
          if (savedClosureClass == null) {
            // then this is the top-level closure class
            // have to treat it special: it doesn't contain a field that points 
            // to the top-level closure class. The field introduced to hold the value of the
            // old expression will be declared in this class.
            this.topLevelClosureClass = this.currentClosureClass;
          } else {
            // Find the field in this.closureClass that the C# compiler generated
            // to point to the top-level closure
            foreach (Member mem in this.currentClosureClass.Members) {
              Field f = mem as Field;
              if (f == null) continue;
              if (f.Type == this.topLevelClosureClass) {
                this.PointerToTopLevelClosureClass = f;
                break;
              }
            }
          }

          this.VisitBlock(m.Body);

          if (savedClosureClass == null) {
            this.topLevelClosureClass = null;
          }
          this.currentClosureClass = savedClosureClass;
          this.PointerToTopLevelClosureClass = null;
        }
      }
      JustVisit:
      return base.VisitConstruct(cons);
    }
Beispiel #4
0
    /// <summary>
    /// If there is an anonymous delegate within a postcondition, then there
    /// will be a call to a delegate constructor.
    /// That call looks like "d..ctor(o,m)" where d is the type of the delegate.
    /// There are two cases depending on whether the anonymous delegate captured
    /// anything. In both cases, m is the method implementing the anonymous delegate.
    /// (1) It does capture something. Then o is the instance of the closure class
    /// implementing the delegate, and m is an instance method in the closure
    /// class.
    /// (2) It does *not* capture anything. Then o is the literal for null and
    /// m is a static method that was added directly to the class.
    /// 
    /// This method will cause the method (i.e., m) to be visited to collect any
    /// Result&lt;T&gt;() expressions that occur in it.
    /// </summary>
    /// <param name="cons">The AST representing the call to the constructor
    /// of the delegate type.</param>
    /// <returns>Whatever the base visitor returns</returns>
    public override Expression VisitConstruct(Construct cons) {
      if (cons.Type is DelegateNode) {
        UnaryExpression ue = cons.Operands[1] as UnaryExpression;
        if (ue == null) goto JustVisit;
        MemberBinding mb = ue.Operand as MemberBinding;
        if (mb == null) goto JustVisit;
        Method m = mb.BoundMember as Method;
        if (!HelperMethods.IsCompilerGenerated(m)) goto JustVisit;

        Contract.Assume(m != null);

        m = Definition(m);
        this.delegateNestingLevel++;
        TypeNode savedClosureClass = this.currentClosureClassInstance;
        Method savedClosureMethod = this.currentClosureMethod;
        Expression savedCurrentAccessToTopLevelClosure = this.currentAccessToTopLevelClosure;

        try
        {
          this.currentClosureMethod = m;

          if (m.IsStatic)
          {
            this.currentClosureClassInstance = null; // no closure object
          }
          else
          {
            this.currentClosureClassInstance = cons.Operands[0].Type;
            if (savedClosureClass == null)
            {
              // Then this is the top-level closure class.
              this.topLevelClosureClassInstance = this.currentClosureClassInstance;
              this.topLevelClosureClassDefinition = Definition(this.topLevelClosureClassInstance);
              this.currentAccessToTopLevelClosure = new This(this.topLevelClosureClassDefinition);
              this.properlyInstantiatedFieldType = this.originalLocalForResult.Type;

              if (this.topLevelMethodFormals != null) 
              {
                Contract.Assume(this.topLevelClosureClassDefinition.IsGeneric);
                Contract.Assume(topLevelClosureClassDefinition.TemplateParameters.Count >= this.topLevelMethodFormals.Count);

                // replace method type parameters in result properly with last n corresponding type parameters of closure class
                TypeNodeList closureFormals = topLevelClosureClassDefinition.TemplateParameters;
                if (closureFormals.Count > this.topLevelMethodFormals.Count)
                {
                  int offset = closureFormals.Count - this.topLevelMethodFormals.Count;
                  closureFormals = new TypeNodeList(this.topLevelMethodFormals.Count);
                  for (int i = 0; i < this.topLevelMethodFormals.Count; i++)
                  {
                    closureFormals.Add(topLevelClosureClassDefinition.TemplateParameters[i + offset]);
                  }
                }
                Duplicator dup = new Duplicator(this.declaringType.DeclaringModule, this.declaringType);
                Specializer spec = new Specializer(this.declaringType.DeclaringModule, topLevelMethodFormals, closureFormals);
                var type = dup.VisitTypeReference(this.originalLocalForResult.Type);
                type = spec.VisitTypeReference(type);
                this.properlyInstantiatedFieldType = type;
              }
            }
            else
            {
              while (currentClosureClassInstance.Template != null) currentClosureClassInstance = currentClosureClassInstance.Template;

              // Find the field in this.closureClass that the C# compiler generated
              // to point to the top-level closure
              foreach (Member mem in this.currentClosureClassInstance.Members)
              {
                Field f = mem as Field;
                if (f == null) continue;
                if (f.Type == this.topLevelClosureClassDefinition)
                {
                  var consolidatedTemplateParams = this.currentClosureClassInstance.ConsolidatedTemplateParameters;
                  TypeNode thisType;
                  if (consolidatedTemplateParams != null && consolidatedTemplateParams.Count > 0) {
                    thisType = this.currentClosureClassInstance.GetGenericTemplateInstance(this.assemblyBeingRewritten, consolidatedTemplateParams);
                  }
                  else {
                    thisType = this.currentClosureClassInstance;
                  }
                  this.currentAccessToTopLevelClosure = new MemberBinding(new This(thisType), f);

                  break;
                }
              }
            }
          }
          this.VisitBlock(m.Body);
        }
        finally
        {
          this.delegateNestingLevel--;
          this.currentClosureMethod = savedClosureMethod;
          this.currentClosureClassInstance = savedClosureClass;
          this.currentAccessToTopLevelClosure = savedCurrentAccessToTopLevelClosure;
        }
      }
    JustVisit:
      return base.VisitConstruct(cons);
    }
 public override Expression VisitConstruct(Construct cons) {
   isMRNAO = true;
   return cons;
 }
 public override Expression VisitConstruct(Construct cons) {
   hasCall = true;
   return cons;
 }
Beispiel #7
0
        public override Expression VisitConstruct(Construct cons)
        {
            Write("new ");

            TypeExpression te = cons.Constructor.Type as TypeExpression;

            if (te != null)
                this.VisitExpression(te.Expression);
            else if (cons.Constructor.Type.FullName != null)
                Write(cons.Constructor.Type.FullName);
            else
                throw new NotImplementedException("Unexpected constructor style");

            Write("(");
            this.VisitExpressionList(cons.Operands);
            Write(")");
            return cons;
        }
Beispiel #8
0
    internal Class CreateSerializerFor(TypeNode type) {
      // todo: look in the genCache for other serializer assemblies that may have already
      // created the serializer for this type and make an assembly reference to that 
      // serializer instead of creating a complete duplicate.
      TypeNode saved = tempChecker.currentType;

      Class c = (Class)serializers[type];
      if (c != null) return c;
      c = new Class();      
      c.Flags = TypeFlags.Class | TypeFlags.BeforeFieldInit;
      // copy the accessibility of the type we are serializing.
      c.Flags |= (type.Flags & (TypeFlags.Public | TypeFlags.NestedAssembly));
      c.Name = Identifier.For(GetSerializerName(type));
      c.Namespace = Identifier.For(GetSerializerNamespace(type));
      c.DeclaringModule = this.module;
      c.Members = new MemberList();
      c.Attributes = new AttributeList();
      c.BaseClass = Runtime.XmlSerializer;
      tempChecker.currentType = c;

      InstanceInitializer ii = Runtime.XmlSerializerAttribute.GetConstructor();
      MemberBinding mb = new MemberBinding(null, ii);
      mb.Type = Runtime.XmlSerializerAttribute;
      c.Attributes.Add(new AttributeNode(mb, null));
      if (cunit != null) {
        cunit.Namespaces[0].Types.Add(c);
      }
      this.module.Types.Add(c);

      Identifier typeId = Identifier.For("type"); // what we are writing to.
      Identifier rootName = Identifier.For("rootName"); // what we are writing to.
      Identifier rootNamespace = Identifier.For("rootNamespace"); // what we are writing to.

      // Constructor
      Method constructor = new InstanceInitializer();
      constructor.Name = StandardIds.Ctor;
      constructor.DeclaringType = c;
      constructor.Flags = MethodFlags.Public|MethodFlags.HideBySig|MethodFlags.SpecialName|MethodFlags.RTSpecialName;
      constructor.Parameters = new ParameterList();
      constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, typeId, SystemTypes.Type, null, null));
      constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootName, SystemTypes.String, null, null));
      constructor.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootNamespace, SystemTypes.String, null, null));
      constructor.ReturnType = SystemTypes.Void;
      c.Members.Add(constructor);

      // pass args thru to base XmlSerializer constructor.
      Block b = constructor.Body = new Block(new StatementList());
      b.Statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor), 
        new ExpressionList(typeId, rootName, rootNamespace), NodeType.Call)));      
      //AddConsoleWrite(b.Statements, new Literal("Hello!!",SystemTypes.String));

      // Serialize(T source, XmlSerializationWriter writer) method
      Identifier src = Identifier.For("source"); // object being serialized.
      Identifier writer = Identifier.For("writer"); // what we are writing to.

      Method serialize = new Method();
      serialize.Name = Identifier.For("Serialize");        
      serialize.DeclaringType = c;
      serialize.Flags = MethodFlags.Public|MethodFlags.Static|MethodFlags.HideBySig;
      serialize.Parameters = new ParameterList();
      serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, src, type, null, null));
      serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, writer, Runtime.XmlSerializationWriter, null, null));
      serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootName, SystemTypes.String, null, null));
      serialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, rootNamespace, SystemTypes.String, null, null));
      serialize.ReturnType = SystemTypes.Void;
      c.Members.Add(serialize);

      // T Deserialize(XmlReader reader, bool required, out bool result) method
      Identifier reader = Identifier.For("reader"); // what we are reading from.
      Identifier required = Identifier.For("required"); // whether an object is required or not.
      Identifier result = Identifier.For("result"); // whether we found anything.

      Method deserialize = new Method();
      deserialize.Name = Identifier.For("Deserialize");        
      deserialize.DeclaringType = c;
      deserialize.Flags = MethodFlags.Public|MethodFlags.Static|MethodFlags.HideBySig;
      deserialize.Parameters = new ParameterList();
      deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, reader, Runtime.XmlSerializationReader, null, null));
      deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.In, required, SystemTypes.Boolean, null, null));
      deserialize.Parameters.Add(new Parameter(new AttributeList(), ParameterFlags.Out, result, SystemTypes.Boolean.GetReferenceType(), null, null));
      deserialize.ReturnType = type;
      c.Members.Add(deserialize);

      // It is important that we add the serializer to the cache AFTER we create the methods, but 
      // BEFORE we create the method bodies so that we can handle recurrsive calls to AddCallSerializer which
      // happens in recurrsive structures like "class Foo { public Foo f; }".  Otherwise we'd get stuck in an
      // infinite loop.
      serializers[type] = c;

      // Body of serialize method.
      b = serialize.Body = new Block(new StatementList());
      StatementList statements = b.Statements;
      
      if (!AddWriteSimpleType(type, statements, c, writer, src, rootName, rootNamespace)) {
        MethodCall call = new MethodCall();
        call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteStartElement"));
        call.Operands = new ExpressionList();
        call.Operands.Add(rootName);
        call.Operands.Add(rootNamespace);
        statements.Add(new If(new BinaryExpression(rootName,Literal.Null,NodeType.Ne),
          new Block(new StatementList(new ExpressionStatement(call))),null));

        Expression source = src;

        if (type.Template == SystemTypes.GenericBoxed) {
          statements = AddCheckForNull(statements, Duplicate(src, c), type);
          type = Checker.GetCollectionElementType(type); 
          source = CastTo(src, type);//unbox it
        }

        if (type is TupleType) {
          AddWriteTuple(type as TupleType, statements, c, source, writer);
        } else if (type is TypeUnion) {
          AddWriteChoice(type as TypeUnion, statements, c, source, writer);
        } else if (IsStream(type)) {
          AddWriteStream(type, statements, c, source, writer);
        } else {
          SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache);
          SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler);      
          statements = AddCheckForNull(statements, Duplicate(src, c), type);
          AddWriteAttributes(statements, c, writer, source, validator);
          AddWriteContent(type, statements, c, writer, source, validator);        
        }
        call = new MethodCall();
        call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteEndElement"));
        call.Operands = new ExpressionList();
        statements.Add(new If(new BinaryExpression(rootName,Literal.Null,NodeType.Ne),
          new Block(new StatementList(new ExpressionStatement(call))),null));
      }
      // body of deserialize method.
      b = deserialize.Body = new Block(new StatementList());
      statements = b.Statements;

      Local target = new Local(Identifier.Empty, type);

      if (type.Template == SystemTypes.GenericBoxed){
        type = Checker.GetCollectionElementType(type);
      }

      if (type is TupleType) {
        AddReadTuple(b, type as TupleType, statements, reader, target, required, result);
      } else if (type is TypeUnion) {
        AddReadChoice(b, type as TypeUnion, statements, reader, target, required, result);
      } else if (IsStream(type)) {
        AddReadStream(b, type, statements, reader, target, result);
      } else {
        if (type is TypeAlias) {
          type = ((TypeAlias)type).AliasedType;
        }

        // Then we are already positioned on the element to be deserialized. 
        statements.Add(new AssignmentStatement(required, Literal.True));
        if (!AddReadSimpleType(type, statements, reader, target, result, false)) {
          if (!type.IsValueType && !type.IsAbstract && type.GetConstructor() != null) {
            Construct cons = new Construct(new MemberBinding(null, type), new ExpressionList(), type);
            statements.Add(new AssignmentStatement(target, cons));
          }
          SchemaElementDecl sd = SchemaElementDecl.Compile(this.module, type, Checker.GetCollectionElementType(type), this.errorHandler, schemaElementDeclCache);
          SchemaValidator validator = validator = sd.CreateValidator(this.errorHandler);      
          AddReadAttributes(type, statements, reader, target, validator);
          AddReadContent(c, b, type, statements, reader, target, required, result, validator);
        }
      }
      statements.Add(new Return(target));
      tempChecker.currentType = saved;
      return c;
    }
Beispiel #9
0
        public override Expression VisitConstruct(Construct cons)
        {
            if (cons == null) return null;
            //
            // Wrap all Zing allocations in a call to application.Allocate
            //
            Expression ptrAllocation;
            ZArray arrayNode = cons.Type as ZArray;

            if (visitingField)
            {
                if (arrayNode != null)
                    ptrAllocation = Templates.GetExpressionTemplate("InitializerArrayPtrAllocation");
                // Added by Jiri Adamek
                else if (((MemberBinding)cons.Constructor).Type is NativeZOM)
                    ptrAllocation = Templates.GetExpressionTemplate("InitializerNativeZOMPtrAllocation");
                // END of added code
                else
                    ptrAllocation = Templates.GetExpressionTemplate("InitializerPtrAllocation");
            }
            else
            {
                if (arrayNode != null)
                    ptrAllocation = Templates.GetExpressionTemplate("ArrayPtrAllocation");
                // Added by Jiri Adamek
                else if (((MemberBinding)cons.Constructor).Type is NativeZOM)
                    ptrAllocation = Templates.GetExpressionTemplate("NativeZOMPtrAllocation");
                // END of added code
                else
                    ptrAllocation = Templates.GetExpressionTemplate("PtrAllocation");
            }

            if (arrayNode != null)
            {
                if (arrayNode.Sizes == null)
                {
                    // This is a variable-sized array
                    Replacer.Replace(ptrAllocation, "_size", this.VisitExpression(cons.Operands[0]));
                }
                else
                {
                    // This is a constant-sized array
                    Replacer.Replace(ptrAllocation, "_size", new Literal(arrayNode.Sizes[0], SystemTypes.Int32));
                }
            }
            Replacer.Replace(ptrAllocation, "_Constructor", cons.Type.Name);
            Replacer.Replace(ptrAllocation, "_ClassName", new Literal(cons.Type.Name.ToString(), SystemTypes.String));
            return ptrAllocation;
        }
Beispiel #10
0
    /// <summary>
    /// </summary>
    /// <param name="cons">Cloned</param>
    /// <returns></returns>
		public override Expression VisitConstruct(Construct cons)
		{
			ExpressionList operands = this.VisitExpressionList(cons.Operands);
			MemberBinding mb = this.VisitExpression(cons.Constructor) as MemberBinding;
      if (mb == null) return null;

			Debug.Assert(mb.TargetObject == null, "constructor target not null!");

			if ( this.expandAllocations ) 
			{
				// Now split the expression into 3:
				//  allocTemp = new T;
				//  allocTemp..ctor(args...);
				//  allocTemp

				// For value types, the construction is even more involved:
				//  valTemp = new VT;
				//  allocTemp = &valTemp;
				//  allocTemp..ctor(args...);
				//  valTemp

				if (mb.BoundMember != null && mb.BoundMember.DeclaringType != null && mb.BoundMember.DeclaringType.IsValueType) 
				{
					Variable valTemp = StackVariable.NEWValueTemp(mb.BoundMember.DeclaringType);

					Construct newcons = new Construct(new MemberBinding(null, mb.BoundMember), new ExpressionList(0), mb.BoundMember.DeclaringType);
					AssignmentStatement new_stat = new AssignmentStatement(valTemp, newcons);
					new_stat.SourceContext = this.current_source_context;
					new_stats.Add(new_stat);

          Variable allocTemp = StackVariable.NEWTemp(mb.BoundMember.DeclaringType);
          new_stats.Add(new AssignmentStatement(allocTemp, new UnaryExpression(valTemp, NodeType.AddressOf, mb.BoundMember.DeclaringType.GetReferenceType()), NodeType.Nop));
          mb.TargetObject = allocTemp;

					ExpressionStatement call_stat = new ExpressionStatement(new MethodCall(mb, operands, NodeType.Call, Cci.SystemTypes.Void));
					call_stat.SourceContext = this.current_source_context;
					new_stats.Add(call_stat);

					return valTemp;
				}
				else 
				{
					Variable vtemp = StackVariable.NEWTemp(mb.BoundMember.DeclaringType);

					Construct newcons = new Construct(new MemberBinding(null, mb.BoundMember), new ExpressionList(0), mb.BoundMember.DeclaringType);
					AssignmentStatement new_stat = new AssignmentStatement(vtemp, newcons);
					new_stat.SourceContext = this.current_source_context;
					new_stats.Add(new_stat);

					mb.TargetObject = vtemp;

					ExpressionStatement call_stat = new ExpressionStatement(new MethodCall(mb, operands, NodeType.Call, Cci.SystemTypes.Void));
					call_stat.SourceContext = this.current_source_context;
					new_stats.Add(call_stat);

					return vtemp;
				}
			}
			else 
			{
				Construct newcons = new Construct(mb, operands, mb.BoundMember.DeclaringType);
				newcons.SourceContext = this.current_source_context;

				return newcons;
			}
		}
Beispiel #11
0
 public override Expression VisitConstruct(Construct cons)
 {
     if (cons == null) return null;
     Construct result = (Construct)base.VisitConstruct(cons);
     result.Constructor.Type = (TypeNode)this.Visit(result.Constructor.Type);
     return result;
 }
Beispiel #12
0
        public override Expression VisitConstruct(Construct cons)
        {
            if (cons == null) return cons;
            MemberBinding mb = cons.Constructor as MemberBinding;
            if (mb == null)
                return null;

            //
            // Verify that mb.BoundMember is a heap-allocated type
            //
            TypeNode tn = cons.Type;
            ZArray arrayNode = tn as ZArray;
            if (tn is Set || arrayNode != null || tn is Class || tn is Chan)
            {
                if (arrayNode != null)
                {
                    ExpressionList el = cons.Operands;
                    Debug.Assert(el.Count <= 1);
                    if (arrayNode.Sizes == null)
                    {
                        // This is a variable-sized array.  Check that there is exactly
                        // one argument to the constructor of integer type.
                        if (el.Count == 0)
                        {
                            this.HandleError(cons, Error.IntegerExpressionRequired);
                            return null;
                        }
                        Expression e = (Expression)el[0];
                        if (e.Type != SystemTypes.Int32)
                        {
                            this.HandleError(cons, Error.IntegerExpressionRequired);
                            return null;
                        }
                    }
                    else
                    {
                        // This is a constant-sized array.  Check that there is no
                        // argument to the constructor.
                        if (el.Count == 1)
                        {
                            this.HandleError(cons, Error.UnexpectedToken, new string[] { el[0].ToString() });
                            return null;
                        }
                    }
                }
                return cons;
            }
            else
            {
                this.HandleError(cons, Error.ExpectedComplexType);
                return null;
            }
        }
        // Handle bodies of anonymous delegates
        public override void VisitConstruct(Construct cons)
        {
            if (cons.Type.IsDelegateType())
            {
                UnaryExpression ue = cons.Operands[1] as UnaryExpression;
                if (ue == null) goto JustVisit;

                MemberBinding mb = ue.Operand as MemberBinding;
                if (mb == null) goto JustVisit;
                
                Method m = mb.BoundMember as Method;
                
                if (HelperMethods.IsCompilerGenerated(m))
                {
                    bool savedInvisibleMemberRef = this.generatedMethodContainsInvisibleMemberReference;
                    try
                    {
                        this.generatedMethodContainsInvisibleMemberReference = false;
                        
                        var unspecedM = HelperMethods.Unspecialize(m);
                        var unspecedT = unspecedM.DeclaringType;
                        
                        Contract.Assert(unspecedT.Template == null);
                        
                        this.referencingType.Push(unspecedT);
                        this.VisitBlock(unspecedM.Body);
                        
                        if (this.generatedMethodContainsInvisibleMemberReference)
                        {
                            // remove method (and all containing closure methods)
                            savedInvisibleMemberRef = true;
                            for (int i = 0; i < unspecedT.Members.Count; i++)
                            {
                                if (unspecedT.Members[i] == unspecedM)
                                {
                                    unspecedT.Members[i] = null;
                                    break;
                                }
                            }
                        }
                    }
                    finally
                    {
                        this.generatedMethodContainsInvisibleMemberReference = savedInvisibleMemberRef;
                        this.referencingType.Pop();
                    }
                }
            }

            JustVisit:
            
            base.VisitConstruct(cons);
        }
Beispiel #14
0
      public override void VisitConstruct(Construct cons)
      {
        if ((cons.Type.IsDelegateType()))
        {
          UnaryExpression ue = cons.Operands[1] as UnaryExpression;
          if (ue != null)
          {
            MemberBinding mb = ue.Operand as MemberBinding;
            if (mb != null)
            {
              Method m = (Method)mb.BoundMember;
              if (HelperMethods.IsClosureMethod(this.containingType, m) && !HelperMethods.IsClosureType(this.containingType, m.DeclaringType)) 
              {
                // then there is no closure class, m is just a method the compiler
                // added to the class itself

                // we record the instance here, although we will eventually make a copy of the
                // template by making the method generic in its parent type type-parameters.
                MembersToDuplicate.Add(m);
              } else
              {
                //Console.WriteLine("Not atomic closure part: {0}", m.FullName);
                Debug.Assert(m.DeclaringType.Name.Name.Contains("DisplayClass") || !m.Name.Name.Contains("__"));
              }
            }
          }
        }
        base.VisitConstruct(cons);
      }
Beispiel #15
0
 public virtual Expression VisitConstruct(Construct cons)
 {
     if (cons == null) return null;
     cons.Constructor = this.VisitExpression(cons.Constructor);
     cons.Operands = this.VisitExpressionList(cons.Operands);
     cons.Owner = this.VisitExpression(cons.Owner);
     return cons;
 }
            public override void VisitConstruct(Construct cons)
            {
                if (cons == null) return;

                var memberBinding = cons.Constructor as MemberBinding;
                if (memberBinding != null && memberBinding.BoundMember != null &&
                    HelperMethods.DerivesFromException(memberBinding.BoundMember.DeclaringType))
                {
                    this.foundExceptionType = memberBinding.BoundMember.DeclaringType;
                }
            }
Beispiel #17
0
 private Expression ParseNew(TokenSet followers){
   SourceContext ctx = this.scanner.CurrentSourceContext;
   Debug.Assert(this.currentToken == Token.New);
   this.GetNextToken();
   TypeNode allocator = null;
   if (this.currentToken == Token.LeftBracket) {
     this.GetNextToken();
     if (this.currentToken == Token.RightBracket) {
       return this.ParseNewImplicitlyTypedArray(ctx, followers);
     }
     // parse [Delayed] annotation (or allocator)
     allocator = this.ParseBaseTypeExpression(null, followers|Token.RightBracket, false, false);
     if (allocator == null){this.SkipTo(followers, Error.None); return null;}
     this.Skip(Token.RightBracket);
   }
   if (this.currentToken == Token.LeftBrace)
     return this.ParseNewAnonymousTypeInstance(ctx, followers);
   Expression owner = null;
   // Allow owner argument for each constructor: "new <ow> ..."
   if (this.currentToken == Token.LessThan) {
     this.GetNextToken();
     owner = this.ParsePrimaryExpression(followers | Token.GreaterThan);
     if (this.currentToken == Token.GreaterThan)
       this.GetNextToken();
   }
   // Make it explicit that the base type stops at "!", which is handled by
   // the code below.
   TypeNode t = this.ParseBaseTypeExpression(null, followers|Parser.InfixOperators|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis|Token.LogicalNot, false, false);
   if (t == null){this.SkipTo(followers, Error.None); return null;}
   if (this.currentToken == Token.Conditional) {
     TypeNode type = t;
     t = new NullableTypeExpression(type);
     t.SourceContext = type.SourceContext;
     t.SourceContext.EndPos = this.scanner.endPos;
     this.GetNextToken();
   }else if (this.currentToken == Token.LogicalNot){
     TypeNode type = t;
     t = new NonNullableTypeExpression(type);
     t.SourceContext = type.SourceContext;
     t.SourceContext.EndPos = this.scanner.endPos;
     this.GetNextToken();
   }else if (this.currentToken == Token.Multiply){
     this.GetNextToken();
     t = new PointerTypeExpression(t, t.SourceContext);
     t.SourceContext.EndPos = this.scanner.endPos;
     if (!this.inUnsafeCode)
       this.HandleError(t.SourceContext, Error.UnsafeNeeded);
   }
   ctx.EndPos = t.SourceContext.EndPos;
   // special hack [Delayed] in custom allocator position is used to mark the array as
   // a delayed construction. This annotation is used in the Definite Assignment analysis.
   //
   TypeExpression allocatorExp = allocator as TypeExpression;
   if (allocatorExp != null) {
     Identifier allocId = allocatorExp.Expression as Identifier;
     if (allocId != null && allocId.Name == "Delayed") {
       t = new RequiredModifierTypeExpression(t, TypeExpressionFor("Microsoft","Contracts","DelayedAttribute"));
       allocator = null; // not really a custom allocation
     }
   }
   int rank = this.ParseRankSpecifier(false, followers|Token.LeftBrace|Token.LeftBracket|Token.LeftParenthesis|Token.RightParenthesis);
   SourceContext lbCtx = ctx;
   while (rank > 0 && this.currentToken == Token.LeftBracket){
     lbCtx = this.scanner.CurrentSourceContext;
     t = new ArrayTypeExpression(t, rank);
     rank = this.ParseRankSpecifier(false, followers|Token.LeftBrace|Token.LeftBracket);
   }
   if (rank > 0){
     //new T[] {...} or new T[,] {{..} {...}...}, etc where T can also be an array type
     ConstructArray consArr = new ConstructArray();
     consArr.SourceContext = ctx;
     consArr.ElementType = consArr.ElementTypeExpression = t;
     consArr.Rank = rank;
     if (this.currentToken == Token.LeftBrace)
       consArr.Initializers = this.ParseArrayInitializer(rank, t, followers);
     else{
       if (Parser.UnaryStart[this.currentToken])
         this.HandleError(Error.ExpectedLeftBrace);
       else
         this.HandleError(Error.MissingArraySize);
       while (Parser.UnaryStart[this.currentToken]){
         this.ParseExpression(followers|Token.Comma|Token.RightBrace);
         if (this.currentToken != Token.Comma) break;
         this.GetNextToken();
       }
       if (this.currentToken == Token.RightBrace) this.GetNextToken();
       this.SkipTo(followers);
     }
     if (owner != null) {
       consArr.Owner = owner;
     }
     return consArr;
   }
   if (rank < 0){
     //new T[x] or new T[x,y] etc. possibly followed by an initializer or element type rank specifier
     ConstructArray consArr = new ConstructArray();
     consArr.SourceContext = ctx;
     consArr.Operands = this.ParseIndexList(followers|Token.LeftBrace|Token.LeftBracket, lbCtx, out consArr.SourceContext.EndPos);
     rank = consArr.Operands.Count;
     if (this.currentToken == Token.LeftBrace)
       consArr.Initializers = this.ParseArrayInitializer(rank, t, followers);
     else{
       int elementRank = this.ParseRankSpecifier(true, followers);
     tryAgain:
       if (elementRank > 0) t = this.ParseArrayType(elementRank, t, followers);
       if (this.currentToken == Token.LeftBrace)
         consArr.Initializers = this.ParseArrayInitializer(rank, t, followers);
       else{
         if (this.currentToken == Token.LeftBracket){ //new T[x][y] or something like that
           lbCtx = this.scanner.CurrentSourceContext;
           this.GetNextToken();
           SourceContext sctx = this.scanner.CurrentSourceContext;
           this.ParseIndexList(followers, lbCtx, out sctx.EndPos);
           this.HandleError(sctx, Error.InvalidArray);
           elementRank = 1;
           goto tryAgain;
         }else
           this.SkipTo(followers);
       }
     }
     consArr.ElementType = consArr.ElementTypeExpression = t;
     consArr.Rank = rank;
     if (owner != null) {
       consArr.Owner = owner;
     }
     return consArr;
   }
   ExpressionList arguments = null;
   SourceContext lpCtx = this.scanner.CurrentSourceContext;
   bool sawLeftParenthesis = false;
   if (this.currentToken == Token.LeftParenthesis){
     if (rank == 0 && t is NonNullableTypeExpression) {
       this.SkipTo(followers, Error.BadNewExpr);
       return null;
     }
     sawLeftParenthesis = true;
     this.GetNextToken();
     arguments = this.ParseArgumentList(followers, lpCtx, out ctx.EndPos);
   }else if (this.currentToken == Token.LeftBrace){
     Expression quant = this.ParseComprehension(followers);
     arguments = new ExpressionList(quant);
   }else{
     this.SkipTo(followers, Error.BadNewExpr);
     Construct c = new Construct();
     if (t is TypeExpression)
       c.Constructor = new MemberBinding(null, t, t.SourceContext);
     c.SourceContext = ctx;
     return c;
   }
   if (sawLeftParenthesis && this.currentToken == Token.LeftBrace){
   }
   Construct cons = new Construct(new MemberBinding(null, t), arguments);
   cons.SourceContext = ctx;
   if (owner != null)
     cons.Owner = owner;
   return cons;
 }
Beispiel #18
0
    void AddReadStream(Block block, TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression result){
      // Read next element and figure out if it matches the stream element type, if so read it and add it to the list
      // If not, then return (throw an error if there are no items and the list is the non-empty type).

      // flexArray = new flexarray();
      // while (reader.Read() && read.NodeType != XmlNodeType.EndElement) {
      //    if (reader.NodeType == XmlNodeType.Element) {
      //      readchild(flexarray);
      //    }
      // }
      // target = flexArray; 

      Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block);
      Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block);
      Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType, block);
      Local optional = new Local(Identifier.Empty, SystemTypes.Boolean, block);
      Local foundChild = new Local(Identifier.Empty, SystemTypes.Boolean, block);
      statements.Add(new AssignmentStatement(optional, Literal.False));

      TypeNode eType = Checker.GetCollectionElementType(type);
      Local local = new Local(Identifier.Empty, eType, block);
      Method addMethod = null;
      Local localArray = null;

      if (type.Template == SystemTypes.GenericBoxed) {

        addMethod = null; // only needs one!

      } else if (Checker.IsGenericList(type)) {
        //TODO: this call is invalid if the eType is not public
        TypeNode flexArrayType = SystemTypes.GenericList.GetTemplateInstance(this.module, eType);
        localArray = new Local(Identifier.For("stream"+streamCount++), flexArrayType, block);

        statements.Add(new AssignmentStatement(localArray,
          new Construct(new MemberBinding(null, flexArrayType), new ExpressionList(), flexArrayType)));

        addMethod = flexArrayType.GetMethod(Identifier.For("Add"), eType);
      } else  {        
        TypeNode arrayType = SystemTypes.ArrayList;
        localArray = new Local(Identifier.Empty, arrayType, block);
        statements.Add(new AssignmentStatement(localArray,
          new Construct(new MemberBinding(null, arrayType), new ExpressionList(), arrayType)));

        addMethod = arrayType.GetMethod(Identifier.For("Add"), SystemTypes.Object);
      }

      Block whileBody = new Block(new StatementList());
      MethodCall moveToContent = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList());
      BinaryExpression notAtEnd = new BinaryExpression(moveToContent, 
        new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Ne);
      BinaryExpression notEOF = new BinaryExpression(
        new QualifiedIdentifier(reader, Identifier.For("EOF")), Literal.True, NodeType.Ne);

      While w = new While(new BinaryExpression(notAtEnd, notEOF, NodeType.And), whileBody);
      statements.Add(w);

      whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
      whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
      whileBody.Statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));

      StatementList trueStatements = whileBody.Statements;
      if (type.Template == SystemTypes.GenericBoxed){
        type = Checker.GetCollectionElementType(type);
      }

      trueStatements.Add(new AssignmentStatement(foundChild, Literal.False));

      if (eType is TupleType || eType is TypeUnion || IsStream(eType)) {
        AddCallDeserializer(eType, trueStatements, reader, local, optional, foundChild);        
      } else  {
        AddReadChild(whileBody, trueStatements, Checker.GetDefaultElementName(eType), eType, local, reader, foundChild, true, false);
      }

      If ifFound = new If(new BinaryExpression(foundChild, Literal.True, NodeType.Eq),
        new Block(new StatementList()), new Block(new StatementList()));
      ifFound.TrueBlock.Statements.Add(new AssignmentStatement(result, Literal.True)); // set our result to true then.
      ifFound.FalseBlock.Statements.Add(new Exit()); // break out of loop then.

      trueStatements.Add(ifFound);

      if (addMethod == null) {        
        trueStatements.Add(new AssignmentStatement(target, 
          CastTo(local, type))); // box the result.
        trueStatements.Add(new Exit()); // break out of loop we have it!
      } else {
        MemberBinding addCall = new MemberBinding(localArray, addMethod);
        trueStatements.Add(new ExpressionStatement(new MethodCall(addCall, 
          new ExpressionList(new Expression[1] {local}))));
      }

      // clear out the local, it is a struct of some sort.
      if (local.Type.IsValueType && ! local.Type.IsPrimitive) {
        trueStatements.Add(new AssignmentStatement(local, 
          new Construct(new MemberBinding(null,local.Type), new ExpressionList(), local.Type)));
      }

      // end while
      // assign resulting array to the target object (if we have anything to assign).
      If ifResult = new If(new BinaryExpression(result, Literal.True, NodeType.Eq),
        new Block(new StatementList()), null);
      statements.Add(ifResult);
      statements = ifResult.TrueBlock.Statements;

      if (addMethod != null) {
        if (type is ArrayType) {
          // target = (type)localArray.ToArray(etype);
          Method toArray = SystemTypes.ArrayList.GetMethod(Identifier.For("ToArray"), SystemTypes.Type);
          ExpressionList args = new ExpressionList();
          args.Add(new UnaryExpression(new Literal(eType, SystemTypes.Type), NodeType.Typeof, SystemTypes.Type));
          statements.Add(new AssignmentStatement(target, 
            CastTo(new MethodCall(new MemberBinding(localArray, toArray), 
                     args, NodeType.Callvirt, SystemTypes.Array), type)));

        } else if (type.Template == SystemTypes.GenericNonEmptyIEnumerable) {
          // Explicit coercion of IEnumerable to NonEmptyIEnumerable requires constructing 
          // the NonEmptyIEnumerable object passing in the IEnumerable as an argument.
          TypeNode ienumtype = Checker.GetIEnumerableTypeFromNonEmptyIEnumerableStruct(this.module, type);
          Debug.Assert(ienumtype!=null);
          //TODO: this call is invalid if the eType is not public
          TypeNode nonEmptyIEnum = SystemTypes.GenericNonEmptyIEnumerable.GetTemplateInstance(this.module, eType);

          InstanceInitializer ii = nonEmptyIEnum.GetConstructor(ienumtype);
          Construct c = new Construct(new MemberBinding(null, ii), new ExpressionList(localArray), nonEmptyIEnum);
          statements.Add(new AssignmentStatement(target, c));
        } else {
          statements.Add(new AssignmentStatement(target, localArray));
        }
      }
    }
Beispiel #19
0
 public override Expression VisitConstruct(Construct cons)
 {
     if (cons == null) return null;
     return base.VisitConstruct((Construct)cons.Clone());
 }
Beispiel #20
0
        public override Expression VisitConstruct(Construct cons)
        {
            Write("new ");

            this.VisitExpression(cons.Constructor);

            // This only happens for variable-length arrays, and only one
            // parameter is permitted.
            if (cons.Operands.Count > 0)
            {
                Write("[");
                this.VisitExpression(cons.Operands[0]);
                Write("]");
            }

            return cons;
        }
 public EventingVisitor(Action<Construct> visitConstruct) { VisitedConstruct += visitConstruct; } public event Action<Construct> VisitedConstruct; public override Expression VisitConstruct(Construct cons) { if (VisitedConstruct != null) VisitedConstruct(cons); return base.VisitConstruct(cons); }