/// <summary>
		/// Predicate determines if a particular call is virtual or non virtual
		/// </summary>
		/// <param name="call">The call to test</param>
		/// <returns>true if virtual.</returns>
		public static bool IsVirtual(MethodCall call) 
		{
			Method callee = ((MemberBinding)call.Callee).BoundMember as Method;
			if (callee != null) {
				return (callee.IsVirtual && call.NodeType == NodeType.Callvirt);
			}
			return false;
		}
        public override Expression VisitMethodCall(MethodCall call)
        {
            MemberBinding mb = call.Callee as MemberBinding;
            if (mb == null) return call;

            Method calledMethod = mb.BoundMember as Method;
            if (calledMethod == null) return call;

            Method template = calledMethod.Template;

            if (contractNodes.IsOldMethod(template))
            {
                OldExpression oe = new OldExpression(ExtractOldExpression(call));
                oe.Type = call.Type;
                return oe;
            }

            if (contractNodes.IsValueAtReturnMethod(template))
            {
                return new AddressDereference(call.Operands[0], calledMethod.TemplateArguments[0], call.SourceContext);
            }

            if (contractNodes.IsResultMethod(template))
            {
                // check if we are in an Task returning method
                if (this.declaringMethod != null && this.declaringMethod.ReturnType != null)
                {
                    var rt = this.declaringMethod.ReturnType;
                    var templ = rt.Template;

                    if (templ != null && templ.Name.Name == "Task`1" && rt.TemplateArguments != null &&
                        rt.TemplateArguments.Count == 1)
                    {
                        var targ = rt.TemplateArguments[0];
                        if (calledMethod.TemplateArguments[0] == targ)
                        {
                            // use of ReturnValue<T>() instead of ReturnValue<Task<T>>().Result
                            var retExp = new ReturnValue(rt, call.SourceContext);
                            var resultProp = rt.GetProperty(Identifier.For("Result"));
                            if (resultProp != null && resultProp.Getter != null)
                            {
                                return new MethodCall(new MemberBinding(retExp, resultProp.Getter), new ExpressionList());
                            }
                        }
                    }
                }

                return new ReturnValue(calledMethod.ReturnType, call.SourceContext);
            }

            return base.VisitMethodCall(call);
        }
        public override void VisitMethodCall(MethodCall call)
        {
            MemberBinding mb = call.Callee as MemberBinding;
            if (mb == null) return;

            Method calledMethod = mb.BoundMember as Method;
            if (calledMethod == null) return;

            Method template = calledMethod.Template;

            if (template != null && template.Name.Name == "get_Result" && template.DeclaringType.Name.Name == "Task`1")
            {
                // check if callee is result
                var innercall = mb.TargetObject as MethodCall;
                if (innercall != null)
                {
                    MemberBinding mb2 = innercall.Callee as MemberBinding;
                    if (mb2 != null)
                    {
                        Method calledMethod2 = mb2.BoundMember as Method;
                        if (calledMethod2 != null)
                        {
                            Method template2 = calledMethod2.Template;
                            if (contractNodes.IsResultMethod(template2))
                            {
                                this.foundReturnValueTaskResult = true;
                                //return new ReturnValue(calledMethod.DeclaringType.TemplateArguments[0]);
                                return;
                            }
                        }
                    }
                }
            }

            // For async methods calledMethod (Contract.Result) would be called in the generated generic state machine,
            // and calledMethod.ReturnType would be generic type argument and actualResultType can be generic method argument
            // (if async postcondition declared in the generic method from non-generic class).
            // In this case calledMethod.ReturnType would be != this.actualResultType
            // and different comparison logic should be used (reflected in EquivalentGenercTypes method).
            if (this.actualResultType != null && contractNodes.IsResultMethod(template) &&
                (calledMethod.ReturnType == this.actualResultType || EquivalentGenericTypes(calledMethod, actualResultType)))
            {
                // using Contract.Result<T>() in a Task<T> returning method, this is a shorthand for
                // Contract.Result<Task<T>>().Result
                this.foundReturnValueTaskResult = true;
                return;
            }

            base.VisitMethodCall(call);
        }
        public override void VisitMethodCall(MethodCall call)
        {
            MemberBinding mb = call.Callee as MemberBinding;
            if (mb == null) return;

            Method calledMethod = mb.BoundMember as Method;
            if (calledMethod == null) return;

            Method template = calledMethod.Template;

            if (template != null && template.Name.Name == "get_Result" && template.DeclaringType.Name.Name == "Task`1")
            {
                // check if callee is result
                var innercall = mb.TargetObject as MethodCall;
                if (innercall != null)
                {
                    MemberBinding mb2 = innercall.Callee as MemberBinding;
                    if (mb2 != null)
                    {
                        Method calledMethod2 = mb2.BoundMember as Method;
                        if (calledMethod2 != null)
                        {
                            Method template2 = calledMethod2.Template;
                            if (contractNodes.IsResultMethod(template2))
                            {
                                this.foundReturnValueTaskResult = true;
                                //return new ReturnValue(calledMethod.DeclaringType.TemplateArguments[0]);
                                return;
                            }
                        }
                    }
                }
            }

            if (this.actualResultType != null && contractNodes.IsResultMethod(template) &&
                calledMethod.ReturnType == this.actualResultType)
            {
                // using Contract.Result<T>() in a Task<T> returning method, this is a shorthand for
                // Contract.Result<Task<T>>().Result
                this.foundReturnValueTaskResult = true;
                return;
            }

            base.VisitMethodCall(call);
        }
        private static void AddInterfaceImplementationWrapper(Class Class, Method intfMethod, Method baseMethod)
        {
            var d = new Duplicator(Class.DeclaringModule, Class);
            
            d.SkipBodies = true;

            var copy = d.VisitMethod(baseMethod);
            
            copy.Flags = MethodFlags.Private | MethodFlags.HideBySig | MethodFlags.Virtual | MethodFlags.NewSlot |
                         MethodFlags.Final;
            
            copy.ImplementedInterfaceMethods = new MethodList(intfMethod);
            copy.Name = Identifier.For("InheritedInterfaceImplementationContractWrapper$" + intfMethod.Name.Name);
            copy.ClearBody();
            copy.ThisParameter.Type = Class;
            
            var bodyBlock = new Block(new StatementList());
            copy.Body = new Block(new StatementList(bodyBlock));

            // add call to baseMethod
            var calledMethod = (baseMethod.TemplateParameters != null && baseMethod.TemplateParameters.Count > 0)
                ? baseMethod.GetTemplateInstance(Class, copy.TemplateParameters)
                : baseMethod;

            var argList = new ExpressionList();
            for (int i = 0; i < copy.Parameters.Count; i++)
            {
                argList.Add(copy.Parameters[i]);
            }

            var callExpression = new MethodCall(new MemberBinding(copy.ThisParameter, calledMethod), argList);
            if (HelperMethods.IsVoidType(intfMethod.ReturnType))
            {
                bodyBlock.Statements.Add(new ExpressionStatement(callExpression));
            }
            else
            {
                bodyBlock.Statements.Add(new Return(callExpression));
            }
            
            Class.Members.Add(copy);
        }
Beispiel #6
0
        public override Expression VisitMethodCall(MethodCall call)
        {
            // This is a workaround for a bug in the CCI resolver. It can't cope with calls to methods
            // in which some parameters were nulled out because of an error. We check for that case here
            // and null out the entire method call. Reported to Herman on 10/23/04.
            NameBinding nbCallee = call.Callee as NameBinding;
            if (nbCallee != null && nbCallee.BoundMembers.Count > 0)
            {
                ZMethod calleeMethod = (ZMethod)nbCallee.BoundMembers[0];
                for (int n = calleeMethod.Parameters.Count, i = 0; i < n; i++)
                {
                    if (calleeMethod.Parameters[i] == null)
                        return null;
                }
            }
            // end workaround

            Expression result = base.VisitMethodCall(call);
            return result;
        }
Beispiel #7
0
    //================= reader methods ==========================================    
    void AddReadAttributes(TypeNode type, StatementList statements, Identifier reader, Expression target, SchemaValidator validator) {

      if (validator.Attributes != null) {
        Block whileBody = new Block(new StatementList());
        Literal trueLit = Literal.True;
        MethodCall movenext = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToNextAttribute")), new ExpressionList());
        BinaryExpression condition = new BinaryExpression(movenext, trueLit, NodeType.Eq);
        While w = new While(condition, whileBody);
        statements.Add(w);
        Block lastElseBlock = null;

        Local nameLocal = new Local(SystemTypes.String);
        whileBody.Statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
        Local nsLocal = new Local(SystemTypes.String);
        whileBody.Statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));

        foreach (SchemaAttDef ad in validator.Attributes) {
          // todo: any way to do tokenized compares?
          BinaryExpression nameEqual = new BinaryExpression(nameLocal,
            new Literal(ad.Name.Name, SystemTypes.String), NodeType.Eq);
          BinaryExpression nsEqual = new BinaryExpression(nsLocal,
            new Literal(ad.Name.Prefix != null ? ad.Name.Prefix.Name : "", SystemTypes.String), NodeType.Eq);
          Block elseBlock = new Block(new StatementList());
          If ifExpr = new If(new BinaryExpression(nameEqual, nsEqual, NodeType.And), new Block(new StatementList()), elseBlock);
          if (lastElseBlock != null) {
            lastElseBlock.Statements.Add(ifExpr);
          } else {
            whileBody.Statements.Add(ifExpr);
          }
          lastElseBlock = elseBlock;

          // body of if test, parse the attribute value as the specified type.
          Debug.Assert(ad.Member is Field || ad.Member is Property);
          AddReadSimpleType(Checker.GetMemberType(ad.Member), ifExpr.TrueBlock.Statements, reader, GetMemberBinding(target, ad.Member), null, true);
        }
        //todo: report unknown attributes?
      }
    }
Beispiel #8
0
    void AddCallSerializer(TypeNode srcType, StatementList statements, Expression src, Identifier writer, Expression rootName, Expression rootNamespace ) {

      TypeNode type = Unwrap(srcType);

      Class memberSerializer = this.CreateSerializerFor(type);
      // call the Serialize method on it, passing the member we're serializing.
      ExpressionList args = new ExpressionList();
      args.Add(src);
      args.Add(writer);
      args.Add(rootName);
      args.Add(rootNamespace);
      MethodCall call = new MethodCall();
      Method serialize = memberSerializer.GetMethod(Identifier.For("Serialize"), new TypeNode[4] { type, Runtime.XmlSerializationWriter, SystemTypes.String, SystemTypes.String} );
      call.Callee = new MemberBinding(new MemberBinding(null, memberSerializer), serialize);
      call.Operands = args;
      statements.Add( new ExpressionStatement( call ) );    
    }
Beispiel #9
0
    Expression GetConvertToString(TypeNode srcType, Expression src, bool always) {

      TypeNode type = Unwrap(srcType);

      if (type is EnumNode) {
        Method method = SystemTypes.Enum.GetMethod(Identifier.For("ToString"));
        return new MethodCall(new MemberBinding(src, method), 
          new ExpressionList(), NodeType.Callvirt, SystemTypes.String);
      } 
      
      // See if it has a type converter.
      Class converterClass = Checker.GetTypeConverter(type);
      if (converterClass != null) {
        TypeConverter converter = TypeDescriptor.GetConverter(type.GetRuntimeType());
        if (converter != null) {
          Type converterType = converter.GetType();
          AssemblyNode converterAssembly = AssemblyNode.GetAssembly(converterType.Assembly, cache, false, true);
          converterClass = converterAssembly.GetType(Identifier.For(converterType.Namespace), Identifier.For(converterType.Name)) as Class;
          Expression e = tempChecker.GetConverterToString(converter, converterClass, type, src);
          if (e != null) {
            //Do I need to add namespace and assembly reference for type converter?
            return e;
          }
        }   
      }
      if (always) {        
        if (this.tempTypeSystem.ImplicitCoercionFromTo(src, src.Type, SystemTypes.String)) {
          return CastTo(src, SystemTypes.String);
        } else {
          Method method = type.GetMethod(Identifier.For("ToString"));
          if (method != null) {
            MethodCall call = new MethodCall(new MemberBinding(src, method), 
              new ExpressionList(), NodeType.Call, SystemTypes.String);
            if (!src.Type.IsValueType) call.NodeType = NodeType.Callvirt;
            return call;
          }
        }
      }
      return null;
    }
Beispiel #10
0
    bool AddReadSimpleType(TypeNode simpleType, StatementList statements, Identifier reader, Expression mb, Expression result, bool always) {
      TypeNode type = Unwrap(simpleType);

      string method = null;
      Expression conversion = null;

      if (type == SystemTypes.String) {
        method = "ReadStringElement";
      } else if (type == SystemTypes.Boolean) {
        method = "ReadBool";
      } else if (type == SystemTypes.Int8) {
        method = "ReadSByte";
      } else if (type == SystemTypes.Char) {
        method = "ReadChar";
      } else if (type == SystemTypes.DateTime) {
        method = "ReadDateTime";
      } else if (type == SystemTypes.Decimal) {
        method = "ReadDecimal";
      } else if (type == SystemTypes.Double) {
        method = "ReadDouble";
      } else if (type == SystemTypes.Guid) {
        method = "ReadGuid";
      } else if (type == SystemTypes.Int16) {
        method = "ReadInt16";
      } else if (type == SystemTypes.Int32) {
        method = "ReadInt32";
      } else if (type == SystemTypes.Int64) {
        method = "ReadInt64";
      } else if (type == SystemTypes.UInt8) {
        method = "ReadInt8";
      } else if (type == SystemTypes.Single) {
        method = "ReadSingle";
      } else if (type == SystemTypes.TimeSpan) {
        method = "ReadTimeSpan";
      } else if (type == SystemTypes.UInt16) {
        method = "ReadUInt16";
      } else if (type == SystemTypes.UInt32) {
        method = "ReadUInt32";
      } else if (type == SystemTypes.UInt64) {
        method = "ReadUInt64";
      } else {
        // see if there's a type converter for it.
        conversion = GetConvertFromString(type, new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadStringElement")), null), always);         
      }
      if (method != null) {
        conversion = new MethodCall(new QualifiedIdentifier(reader, Identifier.For(method)), null, NodeType.Callvirt, type);
      }
      if (conversion == null)
        return false; // there is no simple conversion!
      
      statements.Add(new AssignmentStatement(mb, CastTo(conversion, simpleType)));      
      if (result != null)
        statements.Add(new AssignmentStatement(result, Literal.True));
      return true;
    }
Beispiel #11
0
        private void GenerateMethodReturn(Block block, AssignmentStatement assignmentStatement, MethodCall call)
        {
            ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember;

            // Eventually, this will be checked by an earlier phase.
            Debug.Assert(method.Parameters.Count == call.Operands.Count);

            // process output parameters and the return value;
            for (int i = 0, n = call.Operands.Count; i < n; i++)
            {
                Parameter param = method.Parameters[i];
                if ((param.Flags & ParameterFlags.Out) != 0 && call.Operands[i] != null && method.Parameters[i] != null)
                {
                    Statement assignOutParam = Templates.GetStatementTemplate("FetchOutputParameter");
                    Replacer.Replace(assignOutParam, "_dest",
                        this.VisitExpression(((UnaryExpression)call.Operands[i]).Operand));
                    Replacer.Replace(assignOutParam, "_paramName", new Identifier("_Lfc_" + method.Parameters[i].Name.Name));
                    Replacer.Replace(assignOutParam, "_Callee", method.Name);
                    Replacer.Replace(assignOutParam, "_CalleeClass", method.DeclaringType.Name);
                    block.Statements.Add(assignOutParam);
                }
            }

            if (assignmentStatement != null)
            {
                Statement assignReturnValue = Templates.GetStatementTemplate("FetchReturnValue");
                Replacer.Replace(assignReturnValue, "_dest", this.VisitExpression(assignmentStatement.Target));
                Replacer.Replace(assignReturnValue, "_CalleeClass", method.DeclaringType.Name);
                Replacer.Replace(assignReturnValue, "_Callee", method.Name);

                block.Statements.Add(assignReturnValue);
            }

            Statement stmt = Templates.GetStatementTemplate("InvalidateLastFunctionCompleted");
            block.Statements.Add(stmt);
        }
Beispiel #12
0
        private void GenerateMethodCall(Block block, MethodCall call, bool callIsAsync)
        {
            ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember;

            // Eventually, this will be checked by an earlier phase.
            Debug.Assert(method.Parameters.Count == call.Operands.Count);

            Statement createCallFrame;
            if (method.DeclaringType is Interface)
            {
                createCallFrame = Templates.GetStatementTemplate("CreateCallFrameForInterface");
                Replacer.Replace(createCallFrame, "_thisExpr", this.VisitExpression(((MemberBinding)call.Callee).TargetObject));
                Replacer.Replace(createCallFrame, "_CreateMethod", new Identifier("Create" + method.Name.Name));
            }
            else
            {
                createCallFrame = Templates.GetStatementTemplate("CreateCallFrame");
            }
            Replacer.Replace(createCallFrame, "_calleeClass", new Identifier(method.DeclaringType.FullName));
            Replacer.Replace(createCallFrame, "_Callee", method.Name);
            block.Statements.Add(createCallFrame);

            // process input parameters
            for (int i = 0, n = call.Operands.Count; i < n; i++)
            {
                Parameter param = method.Parameters[i];

                if ((param.Flags & ParameterFlags.Out) == 0 && call.Operands[i] != null && method.Parameters[i] != null)
                {
                    Statement assignInParam = Templates.GetStatementTemplate("SetInputParameter");
                    Replacer.Replace(assignInParam, "_src", this.VisitExpression(call.Operands[i]));
                    Replacer.Replace(assignInParam, "_paramName", new Identifier("priv_" + method.Parameters[i].Name.Name));
                    block.Statements.Add(assignInParam);
                }
            }

            if (!method.IsStatic)
            {
                Statement setThis = Templates.GetStatementTemplate("SetThis");
                Replacer.Replace(setThis, "_thisExpr", this.VisitExpression(((MemberBinding)call.Callee).TargetObject));
                block.Statements.Add(setThis);
            }

            if (callIsAsync)
            {
                ExpressionStatement asyncInvoke = (ExpressionStatement)Templates.GetStatementTemplate("InvokeAsyncMethod");

                Replacer.Replace(asyncInvoke, "_methodName",
                    new Literal(method.DeclaringType.Name.Name + "." + method.Name.Name, SystemTypes.String));
                Replacer.Replace(asyncInvoke, "_context", splicer.SourceContextConstructor(call.SourceContext));
                Replacer.Replace(asyncInvoke, "_contextAttr", splicer.ContextAttributeConstructor(attributes));

                block.Statements.Add(asyncInvoke);
            }
            else
            {
                block.Statements.Add(Templates.GetStatementTemplate("InvokeMethod"));
                block.Statements.Add(Templates.GetStatementTemplate("SetIsCall"));
            }
        }
Beispiel #13
0
        public override Expression VisitMethodCall(MethodCall call)
        {
            // We only reach this point for calls to predicate methods within "wait"
            // join conditions.
            ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember;

            ExpressionList ctorArgs;
            QualifiedIdentifier methodClass = new QualifiedIdentifier(
                new QualifiedIdentifier(
                    new QualifiedIdentifier(Identifier.For("Z"), Identifier.For("Application")),
                    method.DeclaringType.Name),
                method.Name);

            MethodCall predCall =
                new MethodCall(
                    new QualifiedIdentifier(Identifier.For("p"), Identifier.For("CallPredicateMethod")),
                    new ExpressionList(
                        new Construct(
                            new MemberBinding(null, new TypeExpression(methodClass)),
                            ctorArgs = new ExpressionList())));

            ctorArgs.Add(Identifier.For("application"));

            if (!method.IsStatic)
                ctorArgs.Add(this.VisitExpression(((MemberBinding)call.Callee).TargetObject));

            for (int i = 0, n = call.Operands.Count; i < n; i++)
                ctorArgs.Add(this.VisitExpression(call.Operands[i]));

            return predCall;
        }
            public override void VisitMethodCall(MethodCall call)
            {
                if (call == null) return;

                base.VisitMethodCall(call);

                if (call.Operands != null && call.Operands.Count > 0) return;

                var mb = call.Callee as MemberBinding;
                if (mb == null) return;

                if (!(mb.TargetObject is This)) return;

                var getter = mb.BoundMember as Method;
                if (getter == null) return;

                if (HelperMethods.Unspecialize(getter.DeclaringType) != this.containingType) return;

                if (!getter.IsPropertyGetter) return;

                if (!HelperMethods.IsAutoPropertyMember(getter)) return;

                if ((getter.ImplementedInterfaceMethods != null && 0 < getter.ImplementedInterfaceMethods.Count)
                    ||
                    (getter.ImplicitlyImplementedInterfaceMethods != null &&
                     0 < getter.ImplicitlyImplementedInterfaceMethods.Count)
                    || getter.OverridesBaseClassMember)
                    // if the property is an override/implementation, then it is going to inherit any contracts there might be from above
                {
                    return;
                }

                // now we have an auto prop
                // make sure we have a setter too
                Property prop = getter.DeclaringMember as Property;
                if (prop == null) return;

                if (prop.Setter == null) return;

                if (!HelperMethods.IsAutoPropertyMember(prop.Setter)) return;

                if (!IsVisibilityOkay(prop)) return;

                this.foundAutoProperties.Add(prop);
            }
            public override Expression VisitMethodCall(MethodCall call)
            {
                var result = base.VisitMethodCall(call);

                call = result as MethodCall;
                if (call == null) return result;

                var mb = call.Callee as MemberBinding;

                if (IsInvariantCall(mb))
                {
                    if (1 < call.Operands.Count)
                    {
                        Member dummy;
                        this.userMessage = SanitizeUserMessageInternal(this.autoProp.Getter, call.Operands[1], out dummy);
                    }

                    if (2 < call.Operands.Count)
                    {
                        this.conditionString = call.Operands[2] as Literal;
                    }

                    return call.Operands[0];
                }

                if (call.Operands.Count != 0) return call; // only nullary properties.

                if (IsAutoPropGetterCall(mb))
                {
                    if (makeRequires)
                    {
                        return this.autoProp.Setter.Parameters[0];
                    }
                    
                    return new ReturnValue(autoProp.Type);
                }

                return result;
            }
Beispiel #16
0
    void AddCallDeserializer(TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result) {

      Class memberSerializer = this.CreateSerializerFor(type);      
      // call the Deserialize method on it, and assign result to target object.
      ExpressionList args = new ExpressionList();
      args.Add(reader);
      args.Add(required);
      if (result is Local) 
        result = new UnaryExpression(result, NodeType.AddressOf);
      args.Add(result);
      MethodCall call = new MethodCall();
      Method deserialize = memberSerializer.GetMethod(Identifier.For("Deserialize"), new TypeNode[3] { Runtime.XmlSerializationReader, SystemTypes.Boolean, SystemTypes.Boolean.GetReferenceType() } );
      call.Callee = new MemberBinding(new MemberBinding(null, memberSerializer), deserialize);
      call.Operands = args;
      statements.Add(new AssignmentStatement(target, call));
    }
Beispiel #17
0
    bool AddWriteSimpleType(TypeNode simpleType, StatementList statements, TypeNode referringType, Identifier writer, Expression src, Expression name, Expression ns) {

      Identifier method = null;
      TypeNode type = Unwrap(simpleType);

      ExpressionList args = new ExpressionList(src);

      if (type == SystemTypes.String) {
        method = Identifier.For("WriteString");
      } else if( type == SystemTypes.Boolean) {
        method = Identifier.For("WriteBoolean");
      } else if( type == SystemTypes.Int8) {
        method = Identifier.For("WriteSByte");
      } else if( type == SystemTypes.Char) {
        method = Identifier.For("WriteChar");
      } else if( type == SystemTypes.DateTime) {
        method = Identifier.For("WriteDateTime");
      } else if( type == SystemTypes.Decimal) {
        method = Identifier.For("WriteDecimal");
      } else if( type == SystemTypes.Double) {
        method = Identifier.For("WriteDouble");
      } else if( type == SystemTypes.Guid) {
        method = Identifier.For("WriteGuid");
      } else if( type == SystemTypes.Int16) {
        method = Identifier.For("WriteInt16");
      } else if( type == SystemTypes.Int32) {
        method = Identifier.For("WriteInt32");
      } else if( type == SystemTypes.Int64) {
        method = Identifier.For("WriteInt64");
      } else if( type == SystemTypes.UInt8) {
        method = Identifier.For("WriteByte");
      } else if( type == SystemTypes.Single) {
        method = Identifier.For("WriteSingle");
      } else if( type == SystemTypes.TimeSpan) {
        method = Identifier.For("WriteTimeSpan");
      } else if( type == SystemTypes.UInt16 ) {
        method = Identifier.For("WriteUInt16");
      } else if( type == SystemTypes.UInt32) {
        method = Identifier.For("WriteUInt32");
      } else if( type == SystemTypes.UInt64) {
        method = Identifier.For("WriteUInt64");
      } else {
        Expression conversion = GetConvertToString(type, src, false);
        if (conversion != null) {
          statements = AddCheckForNull(statements, Duplicate(src, referringType), type);
          method = Identifier.For("WriteString");
          args = new ExpressionList(conversion);
        } else {
          return false;
        } 
      }
    
      if (name != null) {        
        Identifier id = Checker.GetDefaultElementName(type);
        string defaultName = id.Name;
        string defaultNamespace = (id.Prefix != null) ? id.Prefix.Name : null;
        Expression localName = new Local(SystemTypes.String);
        Expression localNamespace = new Local(SystemTypes.String);
        Expression safeName = name;
        if (name is Literal) {
          if (name == Literal.Null) {
            localName =  new Literal(defaultName, SystemTypes.String);
            localNamespace = new Literal(defaultNamespace, SystemTypes.String);
          } else {
            localName = name;
            localNamespace = ns;
          }
        } else {
          If nameNull = new If(new BinaryExpression(name, Literal.Null, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList()));
          nameNull.TrueBlock.Statements.Add(new AssignmentStatement(localName, new Literal(defaultName, SystemTypes.String)));
          nameNull.TrueBlock.Statements.Add(new AssignmentStatement(localNamespace, new Literal(defaultNamespace, SystemTypes.String)));
          nameNull.FalseBlock.Statements.Add(new AssignmentStatement(localName, name));
          nameNull.FalseBlock.Statements.Add(new AssignmentStatement(localNamespace, ns));
          statements.Add(nameNull);
        }

        MethodCall call = new MethodCall();
        call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteStartElement"));
        call.Operands = new ExpressionList();
        call.Operands.Add(localName);
        call.Operands.Add(localNamespace);
        statements.Add( new ExpressionStatement( call ) );
      }
      StatementList notNull = statements;
      if (!type.IsValueType) {
        notNull = AddCheckForNull(statements, Duplicate(src, referringType), type);
      }        
      notNull.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(writer, method), args)));

      if (name != null) {
        MethodCall call = new MethodCall();
        call.Callee = new QualifiedIdentifier(writer,Identifier.For("WriteEndElement"));
        call.Operands = new ExpressionList();
        statements.Add( new ExpressionStatement( call ) );      
      }
      return true;
    }
Beispiel #18
0
        // The method added by Jiri Adamek
        // It generates NAtiveZOM calls
        private void GenerateNativeZOMCall(Block block, MethodCall call, bool callIsAsync, AssignmentStatement assignmentStatement)
        {
            ZMethod method = (ZMethod)((MemberBinding)call.Callee).BoundMember;

            // Eventually, this will be checked by an earlier phase.
            Debug.Assert(method.Parameters.Count == call.Operands.Count);

            // Asynchronous calls
            Debug.Assert(!callIsAsync, "async not supporrted for NativeZOM calls");

            // Debugging - parameters
            for (int i = 0, n = call.Operands.Count; i < n; i++)
            {
                Parameter param = method.Parameters[i];

                Debug.Assert(param != null);

                // In fact, call.operands[i] MAY BE null due to the error recovery (if the type of the
                // expression does not match the type in the method definition)
                //
                // Debug.Assert(call.Operands[i] != null);

                Debug.Assert((param.Flags & ParameterFlags.Out) == 0, "out parameters not supported for NativeZOM calls");
            }

            Expression typename = new QualifiedIdentifier(new Identifier("Microsoft.Zing"), method.DeclaringType.Name);
            Expression callee;

            if (!method.IsStatic)
            {
                callee = Templates.GetExpressionTemplate("NativeZOMCallee");
                Replacer.Replace(callee, "_TypeName", typename);
                Expression pointer = this.VisitExpression(((MemberBinding)call.Callee).TargetObject);
                Replacer.Replace(callee, "_Pointer", pointer);
                Replacer.Replace(callee, "_MethodName", method.Name);
            }
            else
            {
                callee = Templates.GetExpressionTemplate("NativeZOMStaticCall");
                Replacer.Replace(callee, "_ClassName", typename);
                Replacer.Replace(callee, "_MethodName", method.Name);
            }

            ExpressionList argumentList = new ExpressionList();
            argumentList.Add(Templates.GetExpressionTemplate("NativeZOMCallFirstArgument"));
            foreach (Expression operand in call.Operands) argumentList.Add(this.VisitExpression(operand));
            MethodCall nativeCall = new MethodCall(callee, argumentList);

            Statement newStatement;
            if (assignmentStatement != null)
            {
                newStatement = Templates.GetStatementTemplate("NativeZOMCallWithAssignment");
                Replacer.Replace(newStatement, "_Dest", this.VisitExpression(assignmentStatement.Target));
                Replacer.Replace(newStatement, "_Source", nativeCall);
            }
            else
            {
                newStatement = new ExpressionStatement(nativeCall);
            }

            block.Statements.Add(newStatement);
        }
Beispiel #19
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 #20
0
 public override Expression VisitMethodCall(MethodCall mc){
   Expression result = base.VisitMethodCall(mc);
   mc = result as MethodCall;
   // check for Aggregate types
   if (mc != null && mc.Operands != null && mc.Operands.Count == 1) {
     Literal lit = mc.Callee as Literal;
     if (lit != null && lit.Type == SystemTypes.Type) {
       TypeNode type = (TypeNode) lit.Value;
       if (type != null && type.IsAssignableTo(SystemTypes.IAggregateGroup)) {
         QueryAggregate qa = new QueryAggregate();
         qa.Name = type.Name;
         qa.AggregateType = type;
         qa.Expression = mc.Operands[0];
         qa.SourceContext = mc.SourceContext;
         if (this.currentGroup != null) {
           this.currentGroup.AggregateList.Add(qa);
           qa.Group = this.currentGroup;
         }
         return qa;      
       }
     }
   }
   return result;
 }
Beispiel #21
0
    Expression GetConvertFromString(TypeNode targetType, Expression src, bool always) {
      if (targetType == SystemTypes.String) 
        return src;// nothing to do!

      if (targetType is EnumNode) {
        // e.g. return (DayOfWeek)Enum.Parse(typeof(DayOfWeek),"Sunday");
        Method method = SystemTypes.Enum.GetMethod(Identifier.For("Parse"), new TypeNode[2]{ SystemTypes.Type, SystemTypes.String});
        UnaryExpression typeOfEnum = new UnaryExpression(new MemberBinding(null, targetType), NodeType.Typeof);
        MethodCall call = new MethodCall(new MemberBinding(new MemberBinding(null, targetType), method), 
          new ExpressionList(new Expression[2]{typeOfEnum, src }), NodeType.Call, SystemTypes.Object);
        return CastTo(call, targetType);
      }
      // See if it has a type converter.
      Class converterClass = Checker.GetTypeConverter(targetType);
      if (converterClass != null) {
        TypeConverter converter = TypeDescriptor.GetConverter(targetType.GetRuntimeType());
        if (converter != null) {
          Type converterType = converter.GetType();
          AssemblyNode converterAssembly = AssemblyNode.GetAssembly(converterType.Assembly, cache, false, true);
          converterClass = converterAssembly.GetType(Identifier.For(converterType.Namespace), Identifier.For(converterType.Name)) as Class;          
          Expression e = tempChecker.GetConverterFromString(converter, converterClass, SystemTypes.String, src, SystemTypes.Object);
          if (e != null) {
            //Do I need to add namespace and assembly reference for type converter?
            return CastTo(e, targetType);
          }
        }   
      }
      if (always) {
        // e.g. return PointArray.Parse("10,20 30,40 50,60");
        Method method = targetType.GetImplicitCoercionFromMethod(SystemTypes.String);
        if (method == null) {
          method = targetType.GetMethod(Identifier.For("Parse"), new TypeNode[1]{ SystemTypes.String});
        }
        if (method != null) {
          MemberBinding typeBinding  = new MemberBinding(null, targetType);
          MethodCall call = new MethodCall(new MemberBinding(typeBinding, method), 
            new ExpressionList(new Expression[1]{ src }), NodeType.Call, targetType );
          return call;
        }
      }
      return null;
    }
Beispiel #22
0
 public override InstanceInitializer InjectDefaultConstructor(TypeNode typeNode) {
   if (this.DontInjectDefaultConstructors || typeNode.IsNormalized) return null;
   Class Class = typeNode as Class;
   if (Class != null && Class.Name != null && !(Class is ClassParameter) && ClassHasNoExplicitConstructors(typeNode)) {
     if (Class.IsAbstractSealedContainerForStatics) return null;
     if (Class.PartiallyDefines != null){
       this.InjectDefaultConstructor(Class.PartiallyDefines);
       InstanceInitializer defCons = Class.PartiallyDefines.GetConstructor();
       if (defCons != null && !defCons.HasCompilerGeneratedSignature) 
         defCons = null; //Not an orphan
       if (defCons != null){
         //This is an injected default constructor that is an orphan, adopt it
         defCons.HasCompilerGeneratedSignature = false; //abuse this flag to stop other partial types from adopting it
         Class.Members.Add(defCons);
         Class.BaseClass = ((Class)Class.PartiallyDefines).BaseClass;
       }
       return defCons; //Ok if defCons null, this type should not show up in inheritance chains
     }else{
       //Inject a default constructor
       This thisParameter = new This(Class);
       Class baseClass = Class.BaseClass;
       StatementList statements = new StatementList(2);
       statements.Add(new FieldInitializerBlock(typeNode, false));
       if (baseClass != null) {
         MethodCall mcall = new MethodCall(new QualifiedIdentifier(new Base(), StandardIds.Ctor, typeNode.Name.SourceContext), null);
         mcall.SourceContext = typeNode.Name.SourceContext;
         ExpressionStatement callSupCons = new ExpressionStatement(mcall);
         callSupCons.SourceContext = typeNode.Name.SourceContext;
         statements.Add(callSupCons);
       }
       InstanceInitializer defCons = new InstanceInitializer(typeNode, null, null, new Block(statements));
       defCons.Name = new Identifier(".ctor", typeNode.Name.SourceContext);
       defCons.SourceContext = typeNode.Name.SourceContext;
       defCons.ThisParameter = thisParameter;
       if (typeNode.IsAbstract)
         defCons.Flags |= MethodFlags.Family|MethodFlags.HideBySig;
       else
         defCons.Flags |= MethodFlags.Public|MethodFlags.HideBySig;
       defCons.CallingConvention = CallingConventionFlags.HasThis;
       defCons.IsCompilerGenerated = true;
       typeNode.Members.Add(defCons);
       return defCons;
     }
   }
   return null;
 }
Beispiel #23
0
    void AddWriteChoice(TypeUnion tu, StatementList statements, TypeNode referringType, Expression src, Identifier writer) {
      // generate the following code:
      //    Type srcType = src.GetType();
      //    if (choiceType.IsAssignableFrom(srcType)){ 
      //      XxxxSerializer s = new XxxxSerializer();
      //      s.Serialize((runtimeType)src, writer);
      //    } else if (...) {
      //      // and so on.
      //    }
      // What we cannot do here is by creating nested XmlSerializers
      // based on runtime type because this could cause infinite recurrsion.
      // So we cannot serialize a type union where one of the choices is "object".

      TypeNodeList choices = tu.Types;

      MethodCall call = new MethodCall();
      call.Callee = new QualifiedIdentifier(src, Identifier.For("GetType"));
      call.Operands = new ExpressionList();

      Local local = new Local(SystemTypes.Type);
      statements.Add(new AssignmentStatement(local, call));

      for (int i = 0, n = choices.Length; i < n; i++) {
        TypeNode choiceType = choices[i];
        if (choiceType == null) continue; // type resolution error.

        // if (choiceType.IsAssignableFrom(srcType)){ 
        BinaryExpression condition = new BinaryExpression(
          new MethodCall(
            new QualifiedIdentifier(new UnaryExpression(new MemberBinding(null, choiceType), NodeType.Typeof), Identifier.For("IsAssignableFrom")),
            new ExpressionList(new Expression[] { local })),
          Literal.True,
          NodeType.Eq);

        Block block = new Block();
        block.Statements = new StatementList();
        BinaryExpression cast = CastTo(src, choiceType);

        Expression name = null, ns = null;
        GetNameAndNamespace(choiceType, out name, out ns);
        Expression simplename = name, simplens = ns;

        // Check for choice of type: [string] and match this with XmlTextNode.
        TypeNode unwrapped = UnwrapSingletonTuple(choiceType, true);
        if (unwrapped == null) unwrapped = choiceType;
        if (unwrapped != null && unwrapped.IsPrimitive) {
          simplename = simplens = null;
          choiceType = unwrapped;
        }

        if (!AddWriteSimpleType(choiceType, block.Statements, referringType, writer, cast, simplename, simplens)) {
          AddCallSerializer(choiceType, block.Statements, cast, writer, name, ns);
        }
        If ifStatement = new If(condition, block, null);
        statements.Add(ifStatement);
      } 
    }
Beispiel #24
0
 void AddReadOptional(Block block, StatementList statements, Member mem, Expression target, Identifier reader, Expression result) {
   TypeNode boxed = Checker.GetMemberType(mem);
   TypeNode type = Checker.GetCollectionElementType(boxed);
   statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("MoveToContent")), new ExpressionList())));
   Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String, block);
   Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String, block);
   statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
   statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
   StringBuilder expecting = new StringBuilder();
   Expression isFound = null;
   if (mem.IsAnonymous) {
     isFound = IsStartOf(block, type, statements, nameLocal, nsLocal, expecting);    
   } else {
     ExpressionList args = new ExpressionList();
     args.Add(new Literal(mem.Name.Name, SystemTypes.String));
     isFound = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("IsStartElement")), args);
   }
   StatementList trueStatements = new StatementList();
   If ifIsFound = new If(isFound, new Block(trueStatements), null);
   statements.Add(ifIsFound);
   
   if (!AddReadSimpleType(type, trueStatements, reader, target, result, false)) {
     Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block);
     statements.Add(new AssignmentStatement(localRequired, Literal.True));
     AddCallDeserializer(type, trueStatements, reader, target, localRequired, result);            
   } 
 }
Beispiel #25
0
    void AddReadAllGroup(Class serializer, Block block, TypeNode type, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result, ArrayList members, Member mixedMember) {

      // todo: keep track of which members have been read and report error on duplicates
      MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList());

      Local sb = new Local(SystemTypes.StringBuilder);
      bool isMixed = mixedMember != null;
      if (isMixed) {
        statements.Add(new AssignmentStatement(sb,
          new Construct(new MemberBinding(null, SystemTypes.StringBuilder), new ExpressionList(), SystemTypes.StringBuilder)));
      }

      Block whileBody = new Block(new StatementList());
      BinaryExpression notEndTag = new BinaryExpression(
        new QualifiedIdentifier(reader, Identifier.For("NodeType")) ,
        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(notEndTag, notEOF, NodeType.And), whileBody);
      statements.Add(w);

      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);

      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"))));
      
      Block childBlock = whileBody;

      if (isMixed) {
        // Append the text node to the current StringBuilder contents.
        childBlock = new Block(new StatementList());
        If ifText = new If(IsTextNode(nodeType), new Block(new StatementList()), childBlock);

        whileBody.Statements.Add(ifText);
        ExpressionList args = new ExpressionList();
        args.Add(new QualifiedIdentifier(reader, Identifier.For("Value")));
        ifText.TrueBlock.Statements.Add(new ExpressionStatement(new MethodCall(
          new QualifiedIdentifier(sb, Identifier.For("Append")), args)));
        ifText.TrueBlock.Statements.Add(new ExpressionStatement(read)); // advance to next node
      }      

      If ifElement = new If(new BinaryExpression(nodeType,
        new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq),
        new Block(new StatementList()), new Block(new StatementList()));
      childBlock.Statements.Add(ifElement);
      childBlock = ifElement.TrueBlock;

      //AddConsoleWrite(statements, new Literal("name=",SystemTypes.String));
      //AddConsoleWriteLine(statements, nameLocal);
      //AddConsoleWrite(statements, new Literal("nodeType=",SystemTypes.String));
      //AddConsoleWriteLine(statements, nodeType);

      foreach (NamedNode childNode in members) {
        if (!(childNode.Member is Field || childNode.Member is Property)) {
          AddError(statements, reader, RuntimeError.SerializationOfTypeNotSupported, 
            new Literal(childNode.Member.GetType().FullName, SystemTypes.String));
        } else {
          Expression mb = GetMemberBinding(target, childNode.Member);
          childBlock = AddReadChild(block, childBlock.Statements, childNode.Name, childNode.TypeNode, mb, reader, result, true, false).FalseBlock;
          // todo: throw error if child is required. (e.g. NonEmptyIEnumerable...)
        }
      }
      // if it isn't any of the expected elements then throw an error.
      AddError(childBlock.Statements, reader, RuntimeError.NoSuchMember,
        new Expression[2]{new Literal(tempChecker.GetTypeName(type),SystemTypes.String), nameLocal});

      // If it's not an element then consume it anyway to keep the reader advancing.
      // Probably a comment or PI or something.
      ifElement.FalseBlock.Statements.Add(new ExpressionStatement(new MethodCall(
        new QualifiedIdentifier(reader, Identifier.For("Skip")), new ExpressionList())));

      if (isMixed) {
        statements.Add(new AssignmentStatement(GetMemberBinding(target, mixedMember), 
          new MethodCall(new QualifiedIdentifier(sb, Identifier.For("ToString")), new ExpressionList())));         
      }
      statements.Add(new AssignmentStatement(result, Literal.True));

    }
Beispiel #26
0
    void AddReadChoice(Block block, TypeUnion tu, StatementList statements, Identifier reader, 
      Expression target, Expression required, Expression result){
      // Read next element and figure out which of the choices in the type union it is then read the matching Type.
      
      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);
      statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName"))));
      statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI"))));
      statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));

      Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block);
      statements.Add(new AssignmentStatement(localRequired, Literal.True));

      Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String);
      
      If ifIsElement = new If(new BinaryExpression(nodeType, 
                              new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq),
                              new Block(new StatementList()), new Block(new StatementList()));
      statements.Add(ifIsElement);
        
      StatementList elseList = ifIsElement.TrueBlock.Statements;
      StringBuilder expecting = new StringBuilder();
      Expression bestCoercion = null;
      TypeNode bestChoice = null;
      TypeNode bestUnwrappedChoice = null;
      bool stringCoercionAmbiguous = false;

      for (int i = 0, n = tu.Types.Length; i < n; i++) {
        TypeNode choice = tu.Types[i];
        if (choice == null) continue; // type resolution error.

        TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(choice), false);
        if (unwrapped == null) unwrapped = choice;
        Expression coercion = GetConvertFromString(unwrapped, readString, false);
        if (coercion != null) {
          // Keep track of the best coercion to string and use this to handle text nodes below.
          if (bestChoice == null){
            bestChoice = choice;
            bestUnwrappedChoice = unwrapped;
            bestCoercion = coercion;
          } else if (tempTypeSystem.IsBetterMatch(unwrapped, bestUnwrappedChoice, SystemTypes.String)) {
            bestChoice = choice;
            bestUnwrappedChoice = unwrapped;
            bestCoercion = coercion;
          } else {
            stringCoercionAmbiguous = true;
          }
        }

        BinaryExpression be = IsStartOf(block, choice, statements, nameLocal, nsLocal, expecting);    
        StatementList trueStatements = new StatementList();
        If ifIsStartOf = new If(be, new Block(trueStatements), new Block(new StatementList()));
        elseList.Add(ifIsStartOf);
        Local choiceTarget = new Local(Identifier.Empty, choice, block);
        if (choice.Template == SystemTypes.GenericBoxed){
          choice = Checker.GetCollectionElementType(choice);
        }
        if (!AddReadSimpleType(choice, trueStatements, reader, choiceTarget, result, false)) {
          AddCallDeserializer(choice, trueStatements, reader, choiceTarget, localRequired, result);            
        } 
        trueStatements.Add(new AssignmentStatement(target, 
          CastTo(choiceTarget, target.Type)));

        elseList = ifIsStartOf.FalseBlock.Statements;
      }
      if (bestCoercion != null && !stringCoercionAmbiguous) {      
        // Then we can also accept text nodes
        StatementList ifTextStatements = new StatementList();
        If ifIsText = new If(IsTextNode(nodeType), new Block(ifTextStatements), null);            
        ifIsElement.FalseBlock.Statements.Add(ifIsText);
        // then we can also handle text nodes in this choice.
        ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(bestCoercion, bestChoice), tu)));
        ifTextStatements.Add(new AssignmentStatement(result, Literal.True));        
      }

      // If this was a required element, then throw an error.
      If isRequired = new If(new BinaryExpression(required, Literal.True, NodeType.Eq), 
        new Block(new StatementList()), new Block(new StatementList()));
      elseList.Add(isRequired);
      InvalidContent(isRequired.TrueBlock.Statements, reader, expecting.ToString());
      isRequired.FalseBlock.Statements.Add(new AssignmentStatement(result, Literal.False));

    }
Beispiel #27
0
        public override Expression VisitMethodCall(MethodCall call)
        {
            if (call == null) return null;

            QualifiedIdentifier id = call.Callee as QualifiedIdentifier;
            if (id != null)
            {
                if (id.Identifier.Name == ".ctor")
                    return call;
            }

            this.VisitExpression(call.Callee);
            Write("(");
            this.VisitExpressionList(call.Operands);
            Write(")");
            return call;
        }
Beispiel #28
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));
        }
      }
    }
            /// <summary>
            /// Verifies that method calls are to pure methods.
            /// </summary>
            /// <param name="call">Call to inspect.</param>
            /// <returns><paramref name="call"/></returns>
            public override void VisitMethodCall(MethodCall call)
            {
                // F: Should it be a precondition?
                Contract.Assume(call != null);

                MemberBinding binding = call.Callee as MemberBinding;
                Method method = binding != null ? binding.BoundMember as Method : null;

                bool pure = this.contractNodes.IsPure(method);

                // F: For some reason the code below relies on method != null, and hence to binding call.Callee <: MemberBinding
                Contract.Assume(method != null);

                if (!this.fSharp && !pure && method != this.contractNodes.AssumeMethod)
                {
                    // F:
                    Contract.Assume(this.CurrentMethod != null);

                    this.errorHandler(new Warning(1036,
                        "Detected call to method '" + method.FullName + "' without [Pure] in contracts of method '" +
                        this.CurrentMethod.FullName + "'.", this.lastSourceContext));
                }

                // make sure we now assume this method is pure for the rest of the analysis
                if (!pure)
                {
                    var template = method;

                    while (template.Template != null) template = template.Template;
                    
                    if (template.Contract == null)
                    {
                        template.Contract = new MethodContract(template);
                    }
                    
                    template.Contract.IsPure = true;
                }

                base.VisitMethodCall(call);
            }
Beispiel #30
0
    If AddReadChild(Block scope, StatementList statements, Identifier name, TypeNode type, Expression target, Identifier reader, Expression result, bool unwrapChild, bool ignoreNamespace) {
      ExpressionList args = new ExpressionList();
      args.Add(new Literal(name.Name, SystemTypes.String));
      if (name.Prefix != null) args.Add(new Literal(name.Prefix.Name, SystemTypes.String));
      
      // see if we're on a text node...
      Local nodeType = new Local(Identifier.For("nodeType"), Runtime.XmlNodeType, scope);
      statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType"))));
      StatementList ifTextStatements = new StatementList();      
      If ifIsText = new If(
        new BinaryExpression(IsTextNode(nodeType),
          new BinaryExpression(nodeType,
            new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("EndElement")), NodeType.Eq),
        NodeType.Or), new Block(ifTextStatements), new Block(new StatementList()));            
      statements.Add(ifIsText);
      
      // then see if we can force the text into the desired type.
      TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(type), false);
      if (unwrapped == null) unwrapped = type;
      Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String);
      Expression coercion = GetConvertFromString(unwrapped, readString, false);
      if (coercion != null) {
        ifTextStatements = ifIsText.TrueBlock.Statements;
        ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(coercion, unwrapped),type)));
        ifTextStatements.Add(new AssignmentStatement(result, Literal.True));        
      }
      statements = ifIsText.FalseBlock.Statements;

      If ifFound = null;
      string method = ignoreNamespace ? "IsStartElementIgnoreNamespace" : "IsStartElement";
      MethodCall isStartEle = new MethodCall(new QualifiedIdentifier(reader, Identifier.For(method)), args);
      ifFound = new If(isStartEle, new Block(new StatementList()), new Block(new StatementList()));
      statements.Add(ifFound);
      statements = ifFound.TrueBlock.Statements;       
      
      statements.Add(new AssignmentStatement(result, Literal.True));

      // body of if test, parse the child element as the specified type.
      MethodCall read = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("Read")), new ExpressionList());
      bool isStructuralType = this.IsStructuralType(type);
      if (isStructuralType && unwrapChild) {
        // consume member element wrapper.
        statements.Add(new ExpressionStatement(read));
      }
      if (type.Template == SystemTypes.GenericBoxed){
        type = Checker.GetCollectionElementType(type);
      }

      if (!AddReadSimpleType(type, statements, reader, target, result, false)) {
        AddCallDeserializer(type, statements, reader, target, result, result);
      }
      if (isStructuralType && unwrapChild) {
        // consume member element end tag wrapper.
        statements.Add(new ExpressionStatement(new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadEndTag")), new ExpressionList(new Literal(name.Name, SystemTypes.String)))));
      }
      return ifFound;
    }