Exemple #1
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;
 }
Exemple #2
0
    /// <summary>
    /// Tries to reuse or create the attribute
    /// </summary>
    private static InstanceInitializer GetRuntimeContractsAttributeCtor(AssemblyNode assembly)
    {
      EnumNode runtimeContractsFlags = assembly.GetType(ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsFlags")) as EnumNode;
      Class RuntimeContractsAttributeClass = assembly.GetType(ContractNodes.ContractNamespace, Identifier.For("RuntimeContractsAttribute")) as Class;

      if (runtimeContractsFlags == null)
      {
        #region Add [Flags]
        Member flagsConstructor = RewriteHelper.flagsAttributeNode.GetConstructor();
        AttributeNode flagsAttribute = new AttributeNode(new MemberBinding(null, flagsConstructor), null, AttributeTargets.Class);
        #endregion Add [Flags]
        runtimeContractsFlags = new EnumNode(assembly,
          null, /* declaringType */
          new AttributeList(2),
          TypeFlags.Sealed,
          ContractNodes.ContractNamespace,
          Identifier.For("RuntimeContractsFlags"),
          new InterfaceList(),
          new MemberList());
        runtimeContractsFlags.Attributes.Add(flagsAttribute);
        RewriteHelper.TryAddCompilerGeneratedAttribute(runtimeContractsFlags);
        runtimeContractsFlags.UnderlyingType = SystemTypes.Int32;

        Type copyFrom = typeof(RuntimeContractEmitFlags);
        foreach (System.Reflection.FieldInfo fi in copyFrom.GetFields())
        {
          if (fi.IsLiteral)
          {
            AddEnumValue(runtimeContractsFlags, fi.Name, fi.GetRawConstantValue());
          }
        }
        assembly.Types.Add(runtimeContractsFlags);

      }


      InstanceInitializer ctor = (RuntimeContractsAttributeClass == null) ? null : RuntimeContractsAttributeClass.GetConstructor(runtimeContractsFlags);

      if (RuntimeContractsAttributeClass == null)
      {
        RuntimeContractsAttributeClass = new Class(assembly,
          null, /* declaringType */
          new AttributeList(),
          TypeFlags.Sealed,
          ContractNodes.ContractNamespace,
          Identifier.For("RuntimeContractsAttribute"),
          SystemTypes.Attribute,
          new InterfaceList(),
          new MemberList(0));

        RewriteHelper.TryAddCompilerGeneratedAttribute(RuntimeContractsAttributeClass);
        assembly.Types.Add(RuntimeContractsAttributeClass);
      }
      if (ctor == null) {

        Block returnBlock = new Block(new StatementList(new Return()));

        Block body = new Block(new StatementList());
        Block b = new Block(new StatementList());
        ParameterList pl = new ParameterList();
        Parameter levelParameter = new Parameter(Identifier.For("contractFlags"), runtimeContractsFlags);
        pl.Add(levelParameter);

        ctor = new InstanceInitializer(RuntimeContractsAttributeClass, null, pl, body);
        ctor.Flags = MethodFlags.Assembly | MethodFlags.HideBySig | MethodFlags.SpecialName | MethodFlags.RTSpecialName;

        Method baseCtor = SystemTypes.Attribute.GetConstructor();

        b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, baseCtor), new ExpressionList(ctor.ThisParameter))));
        b.Statements.Add(returnBlock);
        body.Statements.Add(b);

        RuntimeContractsAttributeClass.Members.Add(ctor);
      }

      return ctor;
    }
 public virtual InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons)
 {
     return (InstanceInitializer)this.VisitMethod(cons);
 }
Exemple #4
0
        /// <summary>
        /// There are 2 cases:
        /// 1) Task has no return value. In this case, we emit
        ///      void CheckMethod(Task t) {
        ///         var ae = t.Exception as AggregateException;
        ///         if (ae != null) { ae.Handle(this.CheckException); throw ae; }
        ///      }
        ///      bool CheckException(Exception e) {
        ///          .. check exceptional post
        ///      }
        /// 2) Task(T) returns a T value
        ///      T CheckMethod(Task t) {
        ///         try {
        ///            var r = t.Result;
        ///            .. check ensures on r ..
        ///            return r;
        ///         }
        ///         catch (AggregateException ae) {
        ///            ae.Handle(this.CheckException); 
        ///            throw;
        ///         }
        ///      }
        ///      bool CheckException(Exception e) {
        ///          .. check exceptional post
        ///      }
        /// </summary>
        public EmitAsyncClosure(Method from, Rewriter parent)
        {
            this.fromMethod = from;
            this.parent = parent;
            this.checkMethodId = Identifier.For("CheckPost");
            this.checkExceptionMethodId = Identifier.For("CheckException");
            this.declaringType = from.DeclaringType;
            var closureName = HelperMethods.NextUnusedMemberName(declaringType, "<" + from.Name.Name + ">AsyncContractClosure");
            this.closureClass = new Class(declaringType.DeclaringModule, declaringType, null, TypeFlags.NestedPrivate, null, Identifier.For(closureName), SystemTypes.Object, null, null);
            declaringType.Members.Add(this.closureClass);
            RewriteHelper.TryAddCompilerGeneratedAttribute(this.closureClass);

            this.dup = new Duplicator(this.declaringType.DeclaringModule, this.declaringType);

            var taskType = from.ReturnType;
            var taskArgs = taskType.TemplateArguments == null ? 0 : taskType.TemplateArguments.Count;

            this.AggregateExceptionType = new Cache<TypeNode>(() =>
                HelperMethods.FindType(parent.assemblyBeingRewritten, StandardIds.System, Identifier.For("AggregateException")));
            this.Func2Type = new Cache<TypeNode>(() =>
                HelperMethods.FindType(SystemTypes.SystemAssembly, StandardIds.System, Identifier.For("Func`2")));

            if (from.IsGeneric)
            {
                this.closureClass.TemplateParameters = new TypeNodeList();
                var parentCount = this.declaringType.ConsolidatedTemplateParameters == null ? 0 : this.declaringType.ConsolidatedTemplateParameters.Count;
                for (int i = 0; i < from.TemplateParameters.Count; i++)
                {
                    var tp = HelperMethods.NewEqualTypeParameter(dup, (ITypeParameter)from.TemplateParameters[i], this.closureClass, parentCount + i);

                    this.closureClass.TemplateParameters.Add(tp);
                }
                this.closureClass.IsGeneric = true;
                this.closureClass.EnsureMangledName();
                this.forwarder = new Specializer(this.declaringType.DeclaringModule, from.TemplateParameters, this.closureClass.TemplateParameters);
                this.forwarder.VisitTypeParameterList(this.closureClass.TemplateParameters);

                taskType = this.forwarder.VisitTypeReference(taskType);
            }
            else
            {
                this.closureClassInstance = this.closureClass;
            }

            var taskTemplate = HelperMethods.Unspecialize(taskType);
            var continueWithCandidates = taskTemplate.GetMembersNamed(Identifier.For("ContinueWith"));
            Method continueWithMethod = null;
            for (int i = 0; i < continueWithCandidates.Count; i++)
            {
                var cand = continueWithCandidates[i] as Method;
                if (cand == null) continue;
                if (taskArgs == 0)
                {
                    if (cand.IsGeneric) continue;
                    if (cand.ParameterCount != 1) continue;

                    var p = cand.Parameters[0];
                    var ptype = p.Type;
                    var ptypeTemplate = ptype;

                    while (ptypeTemplate.Template != null)
                    {
                        ptypeTemplate = ptypeTemplate.Template;
                    }

                    if (ptypeTemplate.Name.Name != "Action`1") continue;

                    continueWithMethod = cand;
                    break;
                }
                else
                {
                    if (!cand.IsGeneric) continue;
                    if (cand.TemplateParameters.Count != 1) continue;
                    if (cand.ParameterCount != 1) continue;
                    var p = cand.Parameters[0];
                    var ptype = p.Type;
                    var ptypeTemplate = ptype;
                    while (ptypeTemplate.Template != null)
                    {
                        ptypeTemplate = ptypeTemplate.Template;
                    }
                    if (ptypeTemplate.Name.Name != "Func`2") continue;

                    // now create instance, first of task
                    var taskInstance = taskTemplate.GetTemplateInstance(this.closureClass.DeclaringModule, taskType.TemplateArguments[0]);
                    var candMethod = taskInstance.GetMembersNamed(Identifier.For("ContinueWith"))[i] as Method;
                    continueWithMethod = candMethod.GetTemplateInstance(null, taskType.TemplateArguments[0]);
                    break;
                }
            }

            if (continueWithMethod != null)
            {
                this.continuewithMethod = continueWithMethod;
                EmitCheckMethod(taskType, taskArgs == 1);

                var ctor = new InstanceInitializer(this.closureClass, null, null, null);
                this.constructor = ctor;
                ctor.CallingConvention = CallingConventionFlags.HasThis;
                ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig;
                ctor.Body = new Block(new StatementList(
                    new ExpressionStatement(new MethodCall(new MemberBinding(ctor.ThisParameter, SystemTypes.Object.GetConstructor()), new ExpressionList())),
                    new Return()
                    ));
                this.closureClass.Members.Add(ctor);

            }

            // now that we added the ctor and the check method, let's instantiate the closure class if necessary
            if (this.closureClassInstance == null)
            {
                var consArgs = new TypeNodeList();
                var args = new TypeNodeList();
                var parentCount = this.closureClass.DeclaringType.ConsolidatedTemplateParameters == null ? 0 : this.closureClass.DeclaringType.ConsolidatedTemplateParameters.Count;
                
                for (int i = 0; i < parentCount; i++)
                {
                    consArgs.Add(this.closureClass.DeclaringType.ConsolidatedTemplateParameters[i]);
                }
                
                var methodCount = from.TemplateParameters == null ? 0: from.TemplateParameters.Count;
                for (int i = 0; i < methodCount; i++)
                {
                    consArgs.Add(from.TemplateParameters[i]);
                    args.Add(from.TemplateParameters[i]);
                }

                this.closureClassInstance = (Class)this.closureClass.GetConsolidatedTemplateInstance(this.parent.assemblyBeingRewritten, closureClass.DeclaringType, closureClass.DeclaringType, args, consArgs);
            }

            // create closure initializer for context method
            this.ClosureLocal = new Local(this.ClosureClass);
            this.ClosureInitializer = new Block(new StatementList());

            this.ClosureInitializer.Statements.Add(new AssignmentStatement(this.ClosureLocal, new Construct(new MemberBinding(null, this.Ctor), new ExpressionList())));
        }
Exemple #5
0
        private void EmitCheckMethod(TypeNode taskType, bool hasResult)
        {
            var funcType = this.continuewithMethod.Parameters[0].Type;
            this.funcCtor = funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr);

            var taskParameter = new Parameter(Identifier.For("task"), taskType);
            this.originalResultLocal = new Local(taskParameter.Type);

            if (hasResult)
            {
                this.checkMethod = new Method(this.closureClass, null, this.checkMethodId, new ParameterList(taskParameter), taskType.TemplateArguments[0], null);
                checkMethod.CallingConvention = CallingConventionFlags.HasThis;
                checkMethod.Flags |= MethodFlags.Public;
                this.checkBody = new StatementList();
                var tmpresult = new Local(checkMethod.ReturnType);
                this.newResultLocal = tmpresult;
                checkBody.Add(new AssignmentStatement(this.originalResultLocal, taskParameter));
                checkBody.Add(new AssignmentStatement(tmpresult, new MethodCall(new MemberBinding(checkMethod.Parameters[0], checkMethod.Parameters[0].Type.GetMethod(Identifier.For("get_Result"))), new ExpressionList())));
            }
            else
            {
                this.checkMethod = new Method(this.closureClass, null, this.checkMethodId, new ParameterList(taskParameter), SystemTypes.Void, null);
                checkMethod.CallingConvention = CallingConventionFlags.HasThis;
                checkMethod.Flags |= MethodFlags.Public;
                this.checkBody = new StatementList();
                var aggregateType = AggregateExceptionType.Value;
                this.newResultLocal = new Local(aggregateType);
                checkBody.Add(new AssignmentStatement(this.originalResultLocal, taskParameter));
                checkBody.Add(new AssignmentStatement(this.newResultLocal, new BinaryExpression(new MethodCall(new MemberBinding(checkMethod.Parameters[0], checkMethod.Parameters[0].Type.GetMethod(Identifier.For("get_Exception"))), new ExpressionList()), new MemberBinding(null, aggregateType), NodeType.Isinst)));
            }
            this.closureClass.Members.Add(this.checkMethod);
        }
Exemple #6
0
        public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons)
        {
            WriteStart("{0}", GetMethodQualifiers(cons));
            this.VisitIdentifier(cons.DeclaringType.Name);
            Write("(");
            In();
            cons.Parameters = this.VisitParameterList(cons.Parameters);
            Out();
            Write(")");

            // ISSUE: Is the constructor initializer always statement 1, following the field initializer?

            // Handle the constructor initializer
            if (cons.Body.Statements.Count >= 2)
            {
                for (int n = 0; n < 2; n++)
                {
                    if (cons.Body.Statements[n] is ExpressionStatement)
                    {
                        ExpressionStatement es = (ExpressionStatement)cons.Body.Statements[n];

                        if (es.Expression is MethodCall)
                        {
                            MethodCall mc = (MethodCall)es.Expression;

                            if (mc.Callee is QualifiedIdentifier)
                            {
                                QualifiedIdentifier qi = (QualifiedIdentifier)mc.Callee;

                                if (qi.Identifier.Name == ".ctor")
                                {
                                    // Bingo - this is the constructor initializer

                                    if (mc.Operands != null || !(qi.Qualifier is Base))
                                    {
                                        // We have a non-default initializer, so we must emit it
                                        Write(" : ");
                                        this.VisitExpression(qi.Qualifier);
                                        Write("(");
                                        this.VisitExpressionList(mc.Operands);
                                        Write(")");
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            WriteFinish(string.Empty);

            this.VisitBlock(cons.Body);

            //this.VisitTypeReferenceList(method.ImplementedTypes);
            //this.VisitExpressionList(method.Requires);
            //this.VisitExpressionList(method.Ensures);
            return cons;
        }
Exemple #7
0
    private Class MakeContractException() {
      Class contractExceptionType;

      #region If we're rewriting an assembly for v4 or above and it *isn't* Silverlight (so serialization support is needed), then use new embedded dll as the type
      if (4 <= TargetPlatform.MajorVersion) {
        var iSafeSerializationData = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.Serialization"), Identifier.For("ISafeSerializationData")) as Interface;
        if (iSafeSerializationData != null) {
          // Just much easier to write the C# and have the compiler generate everything than to try and create it all manually
          System.Reflection.Assembly embeddedAssembly;
          Stream embeddedAssemblyStream;
          embeddedAssembly = System.Reflection.Assembly.GetExecutingAssembly();
          embeddedAssemblyStream = embeddedAssembly.GetManifestResourceStream("Microsoft.Contracts.Foxtrot.InternalException.dll");
          byte[] data = new byte[0];
          using (var br = new BinaryReader(embeddedAssemblyStream)) {
            var len = embeddedAssemblyStream.Length;
            if (len < Int32.MaxValue)
              data = br.ReadBytes((int)len);
            AssemblyNode assemblyNode = AssemblyNode.GetAssembly(data, TargetPlatform.StaticAssemblyCache, true, false, true);
            contractExceptionType = assemblyNode.GetType(Identifier.For(""), Identifier.For("ContractException")) as Class;
          }
          if (contractExceptionType == null)
            throw new RewriteException("Tried to create the ContractException type from the embedded dll, but failed");
          var d = new Duplicator(this.targetAssembly, this.RuntimeContractType);
          d.FindTypesToBeDuplicated(new TypeNodeList(contractExceptionType));

          var ct = d.Visit(contractExceptionType);
          contractExceptionType = (Class)ct;
          contractExceptionType.Flags |= TypeFlags.NestedPrivate;
          this.RuntimeContractType.Members.Add(contractExceptionType);
          return contractExceptionType;
        }
      }
      #endregion

      contractExceptionType = new Class(this.targetAssembly, this.RuntimeContractType, new AttributeList(), TypeFlags.Class | TypeFlags.NestedPrivate | TypeFlags.Serializable, null, Identifier.For("ContractException"), SystemTypes.Exception, null, null);

      RewriteHelper.TryAddCompilerGeneratedAttribute(contractExceptionType);

      var kindField = new Field(contractExceptionType, null, FieldFlags.Private, Identifier.For("_Kind"), contractNodes.ContractFailureKind, null);
      var userField = new Field(contractExceptionType, null, FieldFlags.Private, Identifier.For("_UserMessage"), SystemTypes.String, null);
      var condField = new Field(contractExceptionType, null, FieldFlags.Private, Identifier.For("_Condition"), SystemTypes.String, null);
      contractExceptionType.Members.Add(kindField);
      contractExceptionType.Members.Add(userField);
      contractExceptionType.Members.Add(condField);

      #region Constructor for setting the fields
      var parameters = new ParameterList();
      var kindParam = new Parameter(Identifier.For("kind"), this.contractNodes.ContractFailureKind);
      var failureParam = new Parameter(Identifier.For("failure"), SystemTypes.String);
      var usermsgParam = new Parameter(Identifier.For("usermsg"), SystemTypes.String);
      var conditionParam = new Parameter(Identifier.For("condition"), SystemTypes.String);
      var innerParam = new Parameter(Identifier.For("inner"), SystemTypes.Exception);
      parameters.Add(kindParam);
      parameters.Add(failureParam);
      parameters.Add(usermsgParam);
      parameters.Add(conditionParam);
      parameters.Add(innerParam);
      var body = new Block(new StatementList());
      var ctor = new InstanceInitializer(contractExceptionType, null, parameters, body);
      ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig;
      ctor.CallingConvention = CallingConventionFlags.HasThis;
      body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(ctor.ThisParameter, contractExceptionType.BaseClass.GetConstructor(SystemTypes.String, SystemTypes.Exception)), new ExpressionList(failureParam, innerParam))));
      body.Statements.Add(new AssignmentStatement(new MemberBinding(ctor.ThisParameter, kindField), kindParam));
      body.Statements.Add(new AssignmentStatement(new MemberBinding(ctor.ThisParameter, userField), usermsgParam));
      body.Statements.Add(new AssignmentStatement(new MemberBinding(ctor.ThisParameter, condField), conditionParam));
      body.Statements.Add(new Return());
      contractExceptionType.Members.Add(ctor);
      #endregion

      if (SystemTypes.SerializationInfo != null && SystemTypes.SerializationInfo.BaseClass != null) {
        // Silverlight (e.g.) is a platform that doesn't support serialization. So check to make sure the type really exists.
        // 
        var baseCtor = SystemTypes.Exception.GetConstructor(SystemTypes.SerializationInfo, SystemTypes.StreamingContext);

        if (baseCtor != null) {
          #region Deserialization Constructor
          parameters = new ParameterList();
          var info = new Parameter(Identifier.For("info"), SystemTypes.SerializationInfo);
          var context = new Parameter(Identifier.For("context"), SystemTypes.StreamingContext);
          parameters.Add(info);
          parameters.Add(context);
          body = new Block(new StatementList());
          ctor = new InstanceInitializer(contractExceptionType, null, parameters, body);
          ctor.Flags |= MethodFlags.Private | MethodFlags.HideBySig;
          ctor.CallingConvention = CallingConventionFlags.HasThis;
          // : base(info, context) 
          body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(ctor.ThisParameter, baseCtor), new ExpressionList(info, context))));
          // _Kind = (ContractFailureKind)info.GetInt32("Kind");
          var getInt32 = SystemTypes.SerializationInfo.GetMethod(Identifier.For("GetInt32"), SystemTypes.String);
          body.Statements.Add(new AssignmentStatement(
              new MemberBinding(new This(), kindField),
              new MethodCall(new MemberBinding(info, getInt32), new ExpressionList(new Literal("Kind", SystemTypes.String)))
              ));
          // _UserMessage = info.GetString("UserMessage");
          var getString = SystemTypes.SerializationInfo.GetMethod(Identifier.For("GetString"), SystemTypes.String);
          body.Statements.Add(new AssignmentStatement(
              new MemberBinding(new This(), userField),
              new MethodCall(new MemberBinding(info, getString), new ExpressionList(new Literal("UserMessage", SystemTypes.String)))
              ));
          // _Condition = info.GetString("Condition");
          body.Statements.Add(new AssignmentStatement(
              new MemberBinding(new This(), condField),
              new MethodCall(new MemberBinding(info, getString), new ExpressionList(new Literal("Condition", SystemTypes.String)))
              ));
          body.Statements.Add(new Return());
          contractExceptionType.Members.Add(ctor);
          #endregion

          #region GetObjectData

          var securityCriticalCtor = SystemTypes.SecurityCriticalAttribute.GetConstructor();
          var securityCriticalAttribute = new AttributeNode(new MemberBinding(null, securityCriticalCtor), null, System.AttributeTargets.Method);
          var attrs = new AttributeList(securityCriticalAttribute);
          parameters = new ParameterList();
          info = new Parameter(Identifier.For("info"), SystemTypes.SerializationInfo);
          context = new Parameter(Identifier.For("context"), SystemTypes.StreamingContext);
          parameters.Add(info);
          parameters.Add(context);
          body = new Block(new StatementList());
          var getObjectDataName = Identifier.For("GetObjectData");
          var getObjectData = new Method(contractExceptionType, attrs, getObjectDataName, parameters, SystemTypes.Void, body);
          getObjectData.CallingConvention = CallingConventionFlags.HasThis;
          // public override
          getObjectData.Flags = MethodFlags.Public | MethodFlags.Virtual;
          // base.GetObjectData(info, context);
          var baseGetObjectData = SystemTypes.Exception.GetMethod(getObjectDataName, SystemTypes.SerializationInfo, SystemTypes.StreamingContext);
          body.Statements.Add(new ExpressionStatement(
            new MethodCall(new MemberBinding(new This(), baseGetObjectData), new ExpressionList(info, context), NodeType.Call, SystemTypes.Void)
            ));
          // info.AddValue("Kind", _Kind);
          var addValueObject = SystemTypes.SerializationInfo.GetMethod(Identifier.For("AddValue"), SystemTypes.String, SystemTypes.Object);
          body.Statements.Add(new ExpressionStatement(
            new MethodCall(new MemberBinding(info, addValueObject), new ExpressionList(new Literal("Kind", SystemTypes.String), new BinaryExpression(new MemberBinding(new This(), kindField), new Literal(contractNodes.ContractFailureKind), NodeType.Box)), NodeType.Call, SystemTypes.Void)
            ));
          // info.AddValue("UserMessage", _UserMessage);
          body.Statements.Add(new ExpressionStatement(
            new MethodCall(new MemberBinding(info, addValueObject), new ExpressionList(new Literal("UserMessage", SystemTypes.String), new MemberBinding(new This(), userField)), NodeType.Call, SystemTypes.Void)
            ));
          // info.AddValue("Condition", _Condition);
          body.Statements.Add(new ExpressionStatement(
            new MethodCall(new MemberBinding(info, addValueObject), new ExpressionList(new Literal("Condition", SystemTypes.String), new MemberBinding(new This(), condField)), NodeType.Call, SystemTypes.Void)
            ));

          body.Statements.Add(new Return());
          contractExceptionType.Members.Add(getObjectData);
          #endregion
        }
      }

      this.RuntimeContractType.Members.Add(contractExceptionType);
      return contractExceptionType;
    }
Exemple #8
0
    internal static void Initialize(){
      RuntimeAssembly = Runtime.GetRuntimeAssembly();

      PostCompilationPluginAttributeType = RuntimeAssembly.GetType(Identifier.For("Microsoft.SpecSharp"), Identifier.For("PostCompilationPluginAttribute"));
      ObjectConstructor = SystemTypes.Object.GetConstructor(); 
      IListAdd = SystemTypes.IList.GetMethod(StandardIds.Add, SystemTypes.Object);

#if CCINamespace
      const string ContractsNs = "Microsoft.Contracts";
#else
      const string ContractsNs = "Microsoft.Contracts";
#endif

      MustOverrideAttribute = (Class)GetCompilerRuntimeTypeNodeFor(ContractsNs, "MustOverrideAttribute");
    
    }
 public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) {
   hasCall = true;
   return cons;
 }
Exemple #10
0
 private static void WriteConstructor(InstanceInitializer constructor, TextWriter writer) {
     WriteType(constructor.DeclaringType, writer);
     writer.Write(".#ctor");
     WriteParameters(constructor.Parameters, writer);
 }
Exemple #11
0
 private void ParseConstructor(TypeNode parentType, AttributeList attributes, TokenList modifierTokens,
   SourceContextList modifierContexts, object sctx, SourceContext idCtx, TokenSet followers){
   InstanceInitializer c = new InstanceInitializer(parentType, attributes, null, null, this.TypeExpressionFor(Token.Void));
   this.currentCtor = c;
   c.Name = new Identifier(".ctor", idCtx);
   MethodFlags flags = this.GetMethodFlags(modifierTokens, modifierContexts, parentType, c);
   if ((flags & MethodFlags.Static) != 0){
     this.currentCtor = null; // Can you call "base" in a static ctor?
     this.ParseStaticConstructor(parentType, attributes, modifierTokens, modifierContexts, flags, sctx, idCtx, followers);
     return;
   }
   parentType.Members.Add(c);
   c.Flags |= flags|MethodFlags.HideBySig;
   c.Parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace|Token.Semicolon|Token.Colon|Parser.ContractStart|Token.Where);
   c.HasCompilerGeneratedSignature = false;
   c.Documentation = this.LastDocComment;
   QualifiedIdentifier supCons = new QualifiedIdentifier(new Base(), StandardIds.Ctor, this.scanner.CurrentSourceContext);
   MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call);
   superConstructorCall.SourceContext = this.scanner.CurrentSourceContext;
   StatementList slist = new StatementList();
   Block body = new Block(slist, this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode);
   body.SourceContext = this.scanner.CurrentSourceContext;
   Block iblock = new Block(new StatementList(), this.insideCheckedBlock, this.insideUncheckedBlock, this.inUnsafeCode);
   if (this.currentToken == Token.Colon){
     this.GetNextToken();
     bool savedParsingStatement = this.parsingStatement;
     this.parsingStatement = true;
     superConstructorCall.SourceContext = this.scanner.CurrentSourceContext;
     supCons.SourceContext = this.scanner.CurrentSourceContext;
     bool init = false;
     this.inInstanceConstructor = BaseOrThisCallKind.ColonThisOrBaseSeen;
     if (this.currentToken == Token.This){
       if (this.sink != null) this.sink.StartName(new Identifier(".ctor", this.scanner.CurrentSourceContext));
       supCons.Qualifier = new This(this.scanner.CurrentSourceContext, true);
       this.GetNextToken();
     }else if (this.currentToken == Token.Base){
       if (parentType.IsValueType)
         this.HandleError(Error.StructWithBaseConstructorCall, new ErrorHandler(this.errors).GetMemberSignature(c));
       else if (this.sink != null)
         this.sink.StartName(new Identifier(".ctor", this.scanner.CurrentSourceContext));
       supCons.Qualifier = new Base(this.scanner.CurrentSourceContext, true);
       this.GetNextToken();
     }else{
       if (!init)
         this.SkipTo(followers|Token.LeftBrace|Token.Semicolon|Parser.ContractStart|Token.Where, Error.ThisOrBaseExpected);
       if (this.currentToken != Token.EndOfFile) this.parsingStatement = savedParsingStatement;
       goto parseBody;
     }
     SourceContext lpCtx = this.scanner.CurrentSourceContext;
     this.Skip(Token.LeftParenthesis);
     superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon|Parser.ContractStart|Token.Where, lpCtx, out superConstructorCall.SourceContext.EndPos);
     if (this.currentToken != Token.EndOfFile) this.parsingStatement = savedParsingStatement;
   } else {
     // no colon ==> no "base" or "this" before body of ctor
     if (! parentType.IsValueType)
       this.inInstanceConstructor = BaseOrThisCallKind.None;
   }
 parseBody:
   superConstructorCall.SourceContext.EndPos = this.scanner.endPos;
   supCons.SourceContext.EndPos = this.scanner.endPos;
   bool swallowedSemicolonAlready = false;
   this.ParseMethodContract(c, followers|Token.LeftBrace|Token.Semicolon, ref swallowedSemicolonAlready);
   Block b;
   if (this.parsingContractAssembly)
     b = this.ParseBody(c, sctx, followers, swallowedSemicolonAlready); // only allow semicolon body in contract assemblies
   else
     b = this.ParseBody(c, sctx, followers);
   slist.Add(iblock);
   c.IsDeferringConstructor = supCons.Qualifier is This || this.inInstanceConstructor == BaseOrThisCallKind.InCtorBodyThisSeen;
   if (!c.IsDeferringConstructor){
     slist.Add(new FieldInitializerBlock(parentType,false));
   }
   Block baseOrDeferringCallBlock = new Block(new StatementList(1));
   c.BaseOrDefferingCallBlock = baseOrDeferringCallBlock;
   slist.Add(baseOrDeferringCallBlock);
   if (this.inInstanceConstructor == BaseOrThisCallKind.None || this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen){
     if (!(parentType.IsValueType || this.TypeIsSystemObject(parentType)) || supCons.Qualifier is This)
       baseOrDeferringCallBlock.Statements.Add(new ExpressionStatement(superConstructorCall, superConstructorCall.SourceContext));
   }
   if (b != null){
     slist.Add(b);
     body.SourceContext.EndPos = b.SourceContext.EndPos;
     if ((c.Flags & MethodFlags.PInvokeImpl) != 0 && b.Statements != null && b.Statements.Count > 0)
       body = null;
     else if (this.omitBodies)
       b.Statements = null;
   }else if ((c.Flags & MethodFlags.PInvokeImpl) != 0)
     body = null;
   c.Body = body;
   this.inInstanceConstructor = BaseOrThisCallKind.Disallowed;
   this.currentCtor = null;
 }
Exemple #12
0
        private System.Attribute ConstructAttribute(InstanceInitializer/*!*/ constr, object[] argumentValues)
        {
            //This could execute partially trusted code, so set up a very restrictive execution environment
            //TODO: skip this if the attribute is from a trusted assembly
            System.Reflection.ConstructorInfo consInfo = constr.GetConstructorInfo();
            if(consInfo == null)
                return null;
            //Because we invoke the constructor through reflection, a stack walk is performed. The following two commented-out statements
            //would cause the stack walk to fail.
            //For VS2003 and earlier, we will run the constructor in full trust.
            //For VS2005 and later, we will construct a DynamicMethod, wrap it in a delegate, and invoke that.

            //System.Security.PermissionSet perm = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
            //perm.PermitOnly();
            try
            {
                return consInfo.Invoke(argumentValues) as System.Attribute;
            }
            catch { }
            return null;
        }
Exemple #13
0
        public virtual void ProvideMembers()
        {
            if(this.membersAlreadyProvided)
                return;

            this.membersAlreadyProvided = true;
            this.memberCount = 0;
            MemberList members = this.members = new MemberList();

            //ctor
            ParameterList parameters = new ParameterList();
            parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null));
            parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Method, CoreSystemTypes.IntPtr, null, null));
            InstanceInitializer ctor = new InstanceInitializer(this, null, parameters, null);
            ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig;
            ctor.CallingConvention = CallingConventionFlags.HasThis;
            ctor.ImplFlags = MethodImplFlags.Runtime;
            members.Add(ctor);

            //Invoke
            Method invoke = new Method(this, null, StandardIds.Invoke, this.Parameters, this.ReturnType, null);
            invoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.Virtual;
            invoke.CallingConvention = CallingConventionFlags.HasThis;
            invoke.ImplFlags = MethodImplFlags.Runtime;
            members.Add(invoke);

            //BeginInvoke
            ParameterList dparams = this.parameters;
            int n = dparams == null ? 0 : dparams.Count;
            parameters = new ParameterList();

            for(int i = 0; i < n; i++)
            {
                //^ assert dparams != null;
                Parameter p = dparams[i];
                if(p == null)
                    continue;
                parameters.Add((Parameter)p.Clone());
            }

            parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.callback, SystemTypes.AsyncCallback, null, null));
            parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.Object, CoreSystemTypes.Object, null, null));

            Method beginInvoke = new Method(this, null, StandardIds.BeginInvoke, parameters, SystemTypes.IASyncResult, null);
            beginInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual;
            beginInvoke.CallingConvention = CallingConventionFlags.HasThis;
            beginInvoke.ImplFlags = MethodImplFlags.Runtime;
            members.Add(beginInvoke);

            //EndInvoke
            parameters = new ParameterList();

            for(int i = 0; i < n; i++)
            {
                Parameter p = dparams[i];

                if(p == null || p.Type == null || !(p.Type is Reference))
                    continue;

                parameters.Add((Parameter)p.Clone());
            }

            parameters.Add(new Parameter(null, ParameterFlags.None, StandardIds.result, SystemTypes.IASyncResult, null, null));
            Method endInvoke = new Method(this, null, StandardIds.EndInvoke, parameters, this.ReturnType, null);
            endInvoke.Flags = MethodFlags.Public | MethodFlags.HideBySig | MethodFlags.NewSlot | MethodFlags.Virtual;
            endInvoke.CallingConvention = CallingConventionFlags.HasThis;
            endInvoke.ImplFlags = MethodImplFlags.Runtime;
            members.Add(endInvoke);
            if(!this.IsGeneric)
            {
                TypeNodeList templPars = this.TemplateParameters;
                for(int i = 0, m = templPars == null ? 0 : templPars.Count; i < m; i++)
                {
                    //^ assert templPars != null;
                    TypeNode tpar = templPars[i];
                    if(tpar == null)
                        continue;
                    members.Add(tpar);
                }
            }
        }
        private static InstanceInitializer CreateConstructor(Class closureClass)
        {
            var ctor = new InstanceInitializer(closureClass, null, null, null);
            ctor.CallingConvention = CallingConventionFlags.HasThis;
            ctor.Flags |= MethodFlags.Public | MethodFlags.HideBySig;

            // Regular block that calls base class constructor
            ctor.Body = new Block(
                new StatementList(
                    new ExpressionStatement(
                        new MethodCall(new MemberBinding(ctor.ThisParameter, SystemTypes.Object.GetConstructor()),
                            new ExpressionList())),
                new Return()));
            return ctor;
        }
Exemple #15
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;
    }
 public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) {
   isMRNAO = true;
   return cons;
 }
Exemple #17
0
 /// <summary>
 /// Write out a constructor name
 /// </summary>
 /// <param name="constructor">The constructor for which to write out the name</param>
 /// <param name="sb">The string builder to which the name is written</param>
 private static void WriteConstructor(InstanceInitializer constructor, StringBuilder sb)
 {
     WriteType(constructor.DeclaringType, sb);
     sb.Append(".#ctor");
     WriteParameters(constructor.Parameters, sb);
 }
 public EventingVisitor(Action<InstanceInitializer> visitInstanceInitializer) { VisitedInstanceInitializer += visitInstanceInitializer; } public event Action<InstanceInitializer> VisitedInstanceInitializer; public override InstanceInitializer VisitInstanceInitializer(InstanceInitializer cons) { if (VisitedInstanceInitializer != null) VisitedInstanceInitializer(cons); return base.VisitInstanceInitializer(cons); }