public DuplicatorForContractsAndClosures(Module module, Method sourceMethod, Method targetMethod,
            ContractNodes contractNodes, bool mapParameters)
            : base(module, targetMethod.DeclaringType)
        {
            this.sourceMethod = sourceMethod;
            this.targetMethod = targetMethod;

            this.RemoveNameForLocals = true;

            Duplicator dup = this;

            if (mapParameters)
            {
                if (sourceMethod.ThisParameter != null)
                {
                    if (targetMethod.ThisParameter != null)
                    {
                        dup.DuplicateFor[sourceMethod.ThisParameter.UniqueKey] = targetMethod.ThisParameter;
                    }
                    else
                    {
                        // target is a static wrapper. But duplicator cannot handle This -> Parameter conversion
                        // so we handle it explicitly here in this visitor.
                        replaceThisWithParameter = targetMethod.Parameters[0];
                    }
                }

                if (sourceMethod.Parameters != null && targetMethod.Parameters != null
                    && sourceMethod.Parameters.Count == targetMethod.Parameters.Count)
                {
                    for (int i = 0, n = sourceMethod.Parameters.Count; i < n; i++)
                    {
                        dup.DuplicateFor[sourceMethod.Parameters[i].UniqueKey] = targetMethod.Parameters[i];
                    }
                }
            }

            var originalType = HelperMethods.IsContractTypeForSomeOtherType(sourceMethod.DeclaringType, contractNodes);
            if (originalType != null)
            {
                var contractType = this.contractClass = sourceMethod.DeclaringType;
                while (contractType.Template != null)
                {
                    contractType = contractType.Template;
                }
                    
                while (originalType.Template != null)
                {
                    originalType = originalType.Template;
                }

                // forward ContractType<A,B> -> originalType<A',B'>
                this.contractClassToForward = contractType;
                this.targetTypeToForwardTo = originalType;

                //dup.DuplicateFor[contractType.UniqueKey] = originalType;
            }
        }
        public override Expression VisitParameter(Parameter parameter)
        {
            if (parameter == null) return null;

            var oe = new OldExpression(parameter);
            oe.Type = parameter.Type;

            return oe;
        }
 public override void VisitParameter(Parameter parameter)
 {
     if (parameter == null) return;
     if (this.BoundVars.Contains(parameter) && !this.FoundVariables.Contains(parameter))
     {
         this.FoundVariables.Add(parameter);
         this.FoundReferences.Add(parameter);
     }
 }
        public override Expression VisitParameter(Parameter parameter)
        {
            Expression re = base.VisitParameter(parameter);

            TypeNode typeNode = (TypeNode)parameter.TypeExpression;
            parameterType.Add(typeNode);

            return re;
        }
        public override Expression VisitParameter(Parameter parameter)
        {
            if (parameter == null) return null;

            object result = map[parameter.UniqueKey];
            if (result != null) return (Expression) result;

            return base.VisitParameter(parameter);
        }
        public override Expression VisitParameter(Parameter parameter)
        {
            if (parameter == null) return null;

            if (parameter.DeclaringMethod == abbreviation)
            {
                var argIndex = parameter.ParameterListIndex;

                if (argIndex >= actuals.Count) throw new InvalidOperationException("bad parameter/actual list");

                return (Expression) this.Visit(actuals[argIndex]);
            }

            if (parameter.DeclaringMethod == this.targetMethod)
            {
                // important lower case. Upper case is Duplicator's target method
                return parameter;
            }

            return base.VisitParameter(parameter);
        }
예제 #7
0
    private Method MakeRaiseFailureEventMethod()
    {
      Parameter kindParameter = new Parameter(Identifier.For("kind"), contractNodes.ContractFailureKind);
      Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String);
      Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String);
      Parameter exceptionParameter = new Parameter(Identifier.For("inner"), SystemTypes.Exception);
      ParameterList pl = new ParameterList(kindParameter, messageParameter, conditionTextParameter, exceptionParameter);

      Block body = new Block(new StatementList());
      Method m = new Method(this.RuntimeContractType, null, ContractNodes.RaiseContractFailedEventName, pl, SystemTypes.String, body);
      m.Flags = MethodFlags.Assembly | MethodFlags.Static;
      m.Attributes = new AttributeList();
      this.RuntimeContractType.Members.Add(m);

      //
      // Generate the following
      //

      // return String.Format("{0} failed: {1}: {2}", box(kind), conditionText, message);

      var stringFormat3 = SystemTypes.String.GetMethod(Identifier.For("Format"), SystemTypes.String, SystemTypes.Object, SystemTypes.Object, SystemTypes.Object);
      body.Statements.Add(new Return(new MethodCall(new MemberBinding(null, stringFormat3), new ExpressionList(new Literal("{0} failed: {1}: {2}"), new BinaryExpression(kindParameter, new Literal(contractNodes.ContractFailureKind), NodeType.Box), conditionTextParameter, messageParameter))));

      return m;
    }
예제 #8
0
    private Method MakeRequiresWithExceptionMethod(string name)
    {
      Parameter conditionParameter = new Parameter(Identifier.For("condition"), SystemTypes.Boolean);
      Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String);
      Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String);
      MethodClassParameter typeArg = new MethodClassParameter();
      ParameterList pl = new ParameterList(conditionParameter, messageParameter, conditionTextParameter);

      Block body = new Block(new StatementList());
      Method m = new Method(this.RuntimeContractType, null, Identifier.For(name), pl, SystemTypes.Void, body);
      m.Flags = MethodFlags.Assembly | MethodFlags.Static;
      m.Attributes = new AttributeList();
      m.TemplateParameters = new TypeNodeList(typeArg);
      m.IsGeneric = true;
      this.RuntimeContractType.Members.Add(m);

      typeArg.Name = Identifier.For("TException");
      typeArg.DeclaringMember = m;
      typeArg.BaseClass = SystemTypes.Exception;
      typeArg.ParameterListIndex = 0;
      typeArg.DeclaringModule = this.RuntimeContractType.DeclaringModule;

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

      Block b = new Block(new StatementList());
      b.Statements.Add(new Branch(conditionParameter, returnBlock));
      //
      // Generate the following
      //

      // // message == null means: yes we handled it. Otherwise it is the localized failure message
      // var message = RaiseFailureEvent(ContractFailureKind.Precondition, userMessage, conditionString, null);
      // #if assertOnFailure
      // if (message != null) {
      //   Assert(false, message);
      // }
      // #endif

      var messageLocal = new Local(Identifier.For("msg"), SystemTypes.String);
      
      ExpressionList elist = new ExpressionList();
      elist.Add(this.PreconditionKind);
      elist.Add(messageParameter);
      elist.Add(conditionTextParameter);
      elist.Add(Literal.Null);
      b.Statements.Add(new AssignmentStatement(messageLocal, new MethodCall(new MemberBinding(null, this.RaiseFailureEventMethod), elist)));

      if (this.AssertOnFailure)
      {
        var assertMethod = GetSystemDiagnosticsAssertMethod();
        if (assertMethod != null)
        {
          var skipAssert = new Block();
          b.Statements.Add(new Branch(new UnaryExpression(messageLocal, NodeType.LogicalNot), skipAssert));
          // emit assert call
          ExpressionList assertelist = new ExpressionList();
          assertelist.Add(Literal.False);
          assertelist.Add(messageLocal);
          b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, assertMethod), assertelist)));
          b.Statements.Add(skipAssert);
        }
      }
      // // construct exception
      // Exception obj = null;
      // ConstructorInfo ci = typeof(TException).GetConstructor(new[] { typeof(string), typeof(string) });
      // if (ci != null)
      // {
      //   if (reflection.firstArgName == "paramName") {
      //     exceptionObject = ci.Invoke(new[] { userMessage, message }) as Exception;
      //   }
      //   else {
      //     exceptionObject = ci.Invoke(new[] { message, userMessage }) as Exception;
      //   }
      // }
      // else {
      //   ci = typeof(TException).GetConstructor(new[] { typeof(string) });
      //   if (ci != null)
      //   {
      //     exceptionObject = ci.Invoke(new[] { message }) as Exception;
      //   }
      // }
      var exceptionLocal = new Local(Identifier.For("obj"), SystemTypes.Exception);
      b.Statements.Add(new AssignmentStatement(exceptionLocal, Literal.Null));
      var constructorInfoType = TypeNode.GetTypeNode(typeof(System.Reflection.ConstructorInfo));
      Contract.Assume(constructorInfoType != null);
      var methodBaseType = TypeNode.GetTypeNode(typeof(System.Reflection.MethodBase));
      Contract.Assume(methodBaseType != null);
      var constructorLocal = new Local(Identifier.For("ci"), constructorInfoType);
      Contract.Assume(SystemTypes.Type != null);
      var getConstructorMethod = SystemTypes.Type.GetMethod(Identifier.For("GetConstructor"), SystemTypes.Type.GetArrayType(1));
      var typeofExceptionArg = GetTypeFromHandleExpression(typeArg);
      var typeofString = GetTypeFromHandleExpression(SystemTypes.String);
      var typeArrayLocal = new Local(Identifier.For("typeArray"), SystemTypes.Type.GetArrayType(1));
      var typeArray2 = new ConstructArray();
      typeArray2.ElementType = SystemTypes.Type;
      typeArray2.Rank = 1;
      typeArray2.Operands = new ExpressionList(Literal.Int32Two);
      var typeArrayInit2 = new Block(new StatementList());
      typeArrayInit2.Statements.Add(new AssignmentStatement(typeArrayLocal, typeArray2));
      typeArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(typeArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Type), typeofString));
      typeArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(typeArrayLocal, new ExpressionList(Literal.Int32One), SystemTypes.Type), typeofString));
      typeArrayInit2.Statements.Add(new ExpressionStatement(typeArrayLocal));
      var typeArrayExpression2 = new BlockExpression(typeArrayInit2);
      b.Statements.Add(new AssignmentStatement(constructorLocal, new MethodCall(new MemberBinding(typeofExceptionArg, getConstructorMethod), new ExpressionList(typeArrayExpression2))));
      var elseBlock = new Block();
      b.Statements.Add(new Branch(new UnaryExpression(constructorLocal, NodeType.LogicalNot), elseBlock));
      var endifBlock2 = new Block();

      var invokeMethod = constructorInfoType.GetMethod(Identifier.For("Invoke"), SystemTypes.Object.GetArrayType(1));
      var argArray2 = new ConstructArray();
      argArray2.ElementType = SystemTypes.Object;
      argArray2.Rank = 1;
      argArray2.Operands = new ExpressionList(Literal.Int32Two);
      var argArrayLocal = new Local(Identifier.For("argArray"), SystemTypes.Object.GetArrayType(1));

      var parameterInfoType = TypeNode.GetTypeNode(typeof(System.Reflection.ParameterInfo));
      Contract.Assume(parameterInfoType != null);
      var parametersMethod = methodBaseType.GetMethod(Identifier.For("GetParameters"));
      var get_NameMethod = parameterInfoType.GetMethod(Identifier.For("get_Name"));
      var string_op_EqualityMethod = SystemTypes.String.GetMethod(Identifier.For("op_Equality"), SystemTypes.String, SystemTypes.String);
      var elseArgMsgBlock = new Block();
      var endIfArgMsgBlock = new Block();
      b.Statements.Add(new Branch(new UnaryExpression(new MethodCall(new MemberBinding(null, string_op_EqualityMethod), new ExpressionList(new MethodCall(new MemberBinding(new Indexer(new MethodCall(new MemberBinding(constructorLocal, parametersMethod), new ExpressionList(), NodeType.Callvirt), new ExpressionList(Literal.Int32Zero), parameterInfoType), get_NameMethod), new ExpressionList(), NodeType.Callvirt), new Literal("paramName", SystemTypes.String))), NodeType.LogicalNot), elseArgMsgBlock));

      var argArrayInit2 = new Block(new StatementList());
      argArrayInit2.Statements.Add(new AssignmentStatement(argArrayLocal, argArray2));
      argArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Object), messageParameter));
      argArrayInit2.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32One), SystemTypes.Object), messageLocal));
      argArrayInit2.Statements.Add(new ExpressionStatement(argArrayLocal));
      var argArrayExpression2 = new BlockExpression(argArrayInit2);
      b.Statements.Add(new AssignmentStatement(exceptionLocal, new BinaryExpression(new MethodCall(new MemberBinding(constructorLocal, invokeMethod), new ExpressionList(argArrayExpression2)), new Literal(SystemTypes.Exception), NodeType.Isinst)));
      b.Statements.Add(new Branch(null, endIfArgMsgBlock));
 
      b.Statements.Add(elseArgMsgBlock);
      var argArrayInit2_1 = new Block(new StatementList());
      argArrayInit2_1.Statements.Add(new AssignmentStatement(argArrayLocal, argArray2));
      argArrayInit2_1.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Object), messageLocal));
      argArrayInit2_1.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32One), SystemTypes.Object), messageParameter));
      argArrayInit2_1.Statements.Add(new ExpressionStatement(argArrayLocal));
      var argArrayExpression2_1 = new BlockExpression(argArrayInit2_1);
      b.Statements.Add(new AssignmentStatement(exceptionLocal, new BinaryExpression(new MethodCall(new MemberBinding(constructorLocal, invokeMethod), new ExpressionList(argArrayExpression2_1)), new Literal(SystemTypes.Exception), NodeType.Isinst)));

      b.Statements.Add(endIfArgMsgBlock);

      b.Statements.Add(new Branch(null, endifBlock2));

      b.Statements.Add(elseBlock);
      var typeArray1 = new ConstructArray();
      typeArray1.ElementType = SystemTypes.Type;
      typeArray1.Rank = 1;
      typeArray1.Operands = new ExpressionList(Literal.Int32One);
      var typeArrayInit1 = new Block(new StatementList());
      typeArrayInit1.Statements.Add(new AssignmentStatement(typeArrayLocal, typeArray1));
      typeArrayInit1.Statements.Add(new AssignmentStatement(new Indexer(typeArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Type), typeofString));
      typeArrayInit1.Statements.Add(new ExpressionStatement(typeArrayLocal));
      var typeArrayExpression1 = new BlockExpression(typeArrayInit1);
      b.Statements.Add(new AssignmentStatement(constructorLocal, new MethodCall(new MemberBinding(typeofExceptionArg, getConstructorMethod), new ExpressionList(typeArrayExpression1))));

      b.Statements.Add(new Branch(new UnaryExpression(constructorLocal, NodeType.LogicalNot), endifBlock2));
      var argArray1 = new ConstructArray();
      argArray1.ElementType = SystemTypes.Object;
      argArray1.Rank = 1;
      argArray1.Operands = new ExpressionList(Literal.Int32One);
      var argArrayInit1 = new Block(new StatementList());
      argArrayInit1.Statements.Add(new AssignmentStatement(argArrayLocal, argArray1));
      argArrayInit1.Statements.Add(new AssignmentStatement(new Indexer(argArrayLocal, new ExpressionList(Literal.Int32Zero), SystemTypes.Object), messageLocal));
      argArrayInit1.Statements.Add(new ExpressionStatement(argArrayLocal));
      var argArrayExpression1 = new BlockExpression(argArrayInit1);
      b.Statements.Add(new AssignmentStatement(exceptionLocal, new BinaryExpression(new MethodCall(new MemberBinding(constructorLocal, invokeMethod), new ExpressionList(argArrayExpression1)), new Literal(SystemTypes.Exception), NodeType.Isinst)));

      b.Statements.Add(endifBlock2);

      // // throw it
      // if (exceptionObject == null)
      // {
      //   throw new ArgumentException(displayMessage, message);
      // }
      // else
      // {
      //   throw exceptionObject;
      // }
      var thenBlock3 = new Block();

      b.Statements.Add(new Branch(exceptionLocal, thenBlock3));
      b.Statements.Add(new Throw(new Construct(new MemberBinding(null, SystemTypes.ArgumentException.GetConstructor(SystemTypes.String, SystemTypes.String)), new ExpressionList(messageLocal, messageParameter))));
      b.Statements.Add(thenBlock3);
      b.Statements.Add(new Throw(exceptionLocal));
      b.Statements.Add(returnBlock);
      Contract.Assume(body.Statements != null);
      body.Statements.Add(b);

      Member constructor = null;
      AttributeNode attribute = null;

      #region Add [DebuggerNonUserCodeAttribute]
      if (this.HideFromDebugger) {
        TypeNode debuggerNonUserCode = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Diagnostics"), Identifier.For("DebuggerNonUserCodeAttribute"));
        if (debuggerNonUserCode != null)
        {
            constructor = debuggerNonUserCode.GetConstructor();
            attribute = new AttributeNode(new MemberBinding(null, constructor), null, AttributeTargets.Method);
            m.Attributes.Add(attribute);
        }
      }
      #endregion Add [DebuggerNonUserCodeAttribute]

      TypeNode reliabilityContract = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("ReliabilityContractAttribute"));
      TypeNode consistency = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Consistency"));
      TypeNode cer = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Cer"));
      if (reliabilityContract != null && consistency != null && cer != null)
      {
          constructor = reliabilityContract.GetConstructor(consistency, cer);
          if (constructor != null)
          {
              attribute = new AttributeNode(
                new MemberBinding(null, constructor),
                new ExpressionList(
                  new Literal(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, consistency),
                  new Literal(System.Runtime.ConstrainedExecution.Cer.MayFail, cer)),
                  AttributeTargets.Method
                  );
              m.Attributes.Add(attribute);
          }
      }
      return m;
    }
예제 #9
0
    private Method MakeFailureMethod()
    {
      Parameter kindParameter = new Parameter(Identifier.For("kind"), contractNodes.ContractFailureKind);
      Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String);
      Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String);
      Parameter exceptionParameter = new Parameter(Identifier.For("inner"), SystemTypes.Exception);
      ParameterList pl = new ParameterList(kindParameter, messageParameter, conditionTextParameter, exceptionParameter);

      Block body = new Block(new StatementList());
      Method m = new Method(this.RuntimeContractType, null, ContractNodes.ReportFailureName, pl, SystemTypes.Void, body);
      m.Flags = MethodFlags.Assembly | MethodFlags.Static;
      m.Attributes = new AttributeList();
      this.RuntimeContractType.Members.Add(m);

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

      //
      // Generate the following
      //

      // // message == null means: yes we handled it. Otherwise it is the localized failure message
      // var message = RaiseFailureEvent(kind, userMessage, conditionString, inner);
      // if (message == null) return;

      var messageLocal = new Local(Identifier.For("msg"), SystemTypes.String);

      ExpressionList elist = new ExpressionList();
      elist.Add(kindParameter);
      elist.Add(messageParameter);
      elist.Add(conditionTextParameter);
      elist.Add(exceptionParameter);
      body.Statements.Add(new AssignmentStatement(messageLocal, new MethodCall(new MemberBinding(null, this.RaiseFailureEventMethod), elist)));
      body.Statements.Add(new Branch(new UnaryExpression(messageLocal, NodeType.LogicalNot), returnBlock));

      body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, this.TriggerFailureMethod), new ExpressionList(kindParameter, messageLocal, messageParameter, conditionTextParameter, exceptionParameter))));
      body.Statements.Add(returnBlock);
      return m;
    }
예제 #10
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;
    }
예제 #11
0
    /// <summary>
    /// Constructs (and returns) a method that looks like this:
    /// 
    ///   [System.Diagnostics.DebuggerNonUserCodeAttribute]
    ///   [System.Runtime.ConstrainedExecution.ReliabilityContractReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
    ///   static void name(bool condition, string message, string conditionText){
    ///     if (!condition) {
    ///       System.Diagnostics.Contracts.Contract.Failure(kind, message, conditionText, null);
    ///     }
    ///   }
    ///
    /// Or, if the ContractFailureKind is PostconditionOnException, then the generated method
    /// gets an extra parameter which is an Exception and that parameter is passed to Contract.Failure instead of null
    /// </summary>
    private Method MakeMethod(string name, ContractFailureKind kind)
    {
      Parameter conditionParameter = new Parameter(Identifier.For("condition"), SystemTypes.Boolean);
      Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String);
      Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String);
      Parameter exceptionParameter = new Parameter(Identifier.For("originalException"), SystemTypes.Exception);

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

      Block body = new Block(new StatementList());
      Block b = new Block(new StatementList());
      b.Statements.Add(new Branch(conditionParameter, returnBlock));
      ExpressionList elist = new ExpressionList();
      elist.Add(TranslateKindForBackwardCompatibility(kind));
      elist.Add(messageParameter);
      elist.Add(conditionTextParameter);
      if (kind == ContractFailureKind.PostconditionOnException)
      {
        elist.Add(exceptionParameter);
      }
      else
      {
        elist.Add(Literal.Null);
      }
      b.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, this.FailureMethod), elist)));
      b.Statements.Add(returnBlock);
      body.Statements.Add(b);

      ParameterList pl = new ParameterList(conditionParameter, messageParameter, conditionTextParameter);
      if (kind == ContractFailureKind.PostconditionOnException)
      {
        pl.Add(exceptionParameter);
      }
      Method m = new Method(this.RuntimeContractType, null, Identifier.For(name), pl, SystemTypes.Void, body);
      m.Flags = MethodFlags.Assembly | MethodFlags.Static;
      m.Attributes = new AttributeList();
      this.RuntimeContractType.Members.Add(m);

      Member constructor = null;
      AttributeNode attribute = null;

      #region Add [DebuggerNonUserCodeAttribute]
      if (this.HideFromDebugger) {
        TypeNode debuggerNonUserCode = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Diagnostics"), Identifier.For("DebuggerNonUserCodeAttribute"));
        if (debuggerNonUserCode != null)
        {
          constructor = debuggerNonUserCode.GetConstructor();
          attribute = new AttributeNode(new MemberBinding(null, constructor), null, AttributeTargets.Method);
          m.Attributes.Add(attribute);
        }
      }
      #endregion Add [DebuggerNonUserCodeAttribute]

      TypeNode reliabilityContract = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("ReliabilityContractAttribute"));
      TypeNode consistency = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Consistency"));
      TypeNode cer = SystemTypes.SystemAssembly.GetType(Identifier.For("System.Runtime.ConstrainedExecution"), Identifier.For("Cer"));
      if (reliabilityContract != null && consistency != null && cer != null) {
        constructor = reliabilityContract.GetConstructor(consistency, cer);
        if (constructor != null) {
          attribute = new AttributeNode(
            new MemberBinding(null, constructor),
            new ExpressionList(
              new Literal(System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, consistency),
              new Literal(System.Runtime.ConstrainedExecution.Cer.MayFail, cer)),
              AttributeTargets.Method
              );
          m.Attributes.Add(attribute);
        }
      }
      return m;
    }
예제 #12
0
 private Parameter ParseParameter(TokenSet followers, bool allowRefParameters, bool namesAreOptional, bool typesAreOptional){
   Parameter p = new Parameter();
   p.SourceContext = this.scanner.CurrentSourceContext;
   Token tok = this.currentToken;
   p.Attributes = this.ParseAttributes(null, followers|Parser.ParameterTypeStart);
   p.Flags = ParameterFlags.None;
   bool byRef = false;
   switch(this.currentToken){
     case Token.Out:
       //TODO: error if !allowRefParameters && typesAreOptional
       p.Flags = ParameterFlags.Out;
       goto case Token.Ref;
     case Token.Ref:
       //TODO: error if !allowRefParameters && typesAreOptional
       if (!allowRefParameters)
         this.HandleError(Error.IndexerWithRefParam);
       byRef = true;
       this.GetNextToken();
       if (this.currentToken == Token.Params){
         this.HandleError(Error.ParamsCantBeRefOut);
         this.GetNextToken();
       }
       break;
     case Token.Params:
       //TODO: error if !allowRefParameters && typesAreOptional
       Literal lit = new Literal(TypeExpressionFor("System", "ParamArrayAttribute"), null, this.scanner.CurrentSourceContext);
       AttributeNode paramsAttribute = new AttributeNode(lit, null);
       if (p.Attributes == null) p.Attributes = new AttributeList(1);
       p.Attributes.Add(paramsAttribute);
       this.GetNextToken();
       if (this.currentToken == Token.Out || this.currentToken == Token.Ref){
         this.HandleError(Error.ParamsCantBeRefOut);
         if (this.currentToken == Token.Out) goto case Token.Out;
         goto case Token.Ref;
       }
       break;
   }
   bool voidParam = false;
   if (this.currentToken == Token.Void){
     if (this.inUnsafeCode){
       TypeNode voidT = this.TypeExpressionFor(Token.Void);
       SourceContext sctx = this.scanner.CurrentSourceContext;
       this.GetNextToken();
       sctx.EndPos = this.scanner.endPos;
       this.Skip(Token.Multiply);
       p.Type = p.TypeExpression = new PointerTypeExpression(voidT, sctx);
     }else{
       this.HandleError(Error.NoVoidParameter);
       p.Type = this.TypeExpressionFor(Token.Object);
       p.TypeExpression = new TypeExpression(this.scanner.GetIdentifier(), this.scanner.CurrentSourceContext);
       this.GetNextToken();
       voidParam = true;
     }
   }else if (this.currentToken == Token.Delegate)
     p.Type = p.TypeExpression = this.ParseDelegateDeclaration(null, null, null, TypeFlags.None, p.SourceContext, followers);
   else if (p.Type == null){
     p.Type = p.TypeExpression = this.ParseTypeExpression(null, followers|Parser.IdentifierOrNonReservedKeyword);
   }
   if (byRef) p.Type = p.TypeExpression = new ReferenceTypeExpression(p.Type);
   if ((this.currentToken == Token.Comma || this.currentToken == Token.RightParenthesis) && p.TypeExpression is TypeExpression &&
     ((TypeExpression)p.TypeExpression).Expression is Identifier && typesAreOptional) {
     p.Name = (Identifier)((TypeExpression)p.TypeExpression).Expression;
     p.Type = p.TypeExpression = null;
   }else{
     p.Name = this.scanner.GetIdentifier();
   }
   p.SourceContext.EndPos = this.scanner.endPos;
   if (!voidParam || Parser.IdentifierOrNonReservedKeyword[this.currentToken]){
     if (Parser.IdentifierOrNonReservedKeyword[this.currentToken])
       this.GetNextToken();
     else{
       if (namesAreOptional)
         p.Name = Identifier.Empty;
       else
         this.SkipIdentifierOrNonReservedKeyword();
     }
   }
   if (this.currentToken == Token.LeftBracket){
     this.HandleError(Error.BadArraySyntax);
     int endPos = this.scanner.endPos;
     int rank = this.ParseRankSpecifier(true, followers|Token.LeftBracket);
     if (rank > 0)
       p.Type = p.TypeExpression = this.ParseArrayType(rank, p.Type, followers);
     else{
       this.currentToken = Token.LeftBracket;
       this.scanner.endPos = endPos;
       this.GetNextToken();
       while (!this.scanner.TokenIsFirstAfterLineBreak &&
         this.currentToken != Token.RightBracket && this.currentToken != Token.Comma && this.currentToken != Token.RightParenthesis)
         this.GetNextToken();
       if (this.currentToken == Token.RightBracket) this.GetNextToken();
     }
   }else if (this.currentToken == Token.Assign){
     this.HandleError(Error.NoDefaultArgs);
     this.GetNextToken();
     if (Parser.UnaryStart[this.currentToken]){
       this.ParseExpression(followers);
       return p;
     }
   }
   this.SkipTo(followers);
   return p;
 }
        public DuplicatorForContractsAndClosures(Module module, Method sourceMethod, Method targetMethod,
            ContractNodes contractNodes, bool mapParameters)
            : base(module, targetMethod.DeclaringType)
        {
            this.sourceMethod = sourceMethod;
            this.targetMethod = targetMethod;

            this.RemoveNameForLocals = true;

            Duplicator dup = this;

            if (mapParameters)
            {
                if (sourceMethod.ThisParameter != null)
                {
                    if (targetMethod.ThisParameter != null)
                    {
                        dup.DuplicateFor[sourceMethod.ThisParameter.UniqueKey] = targetMethod.ThisParameter;
                    }
                    else
                    {
                        // target is a static wrapper. But duplicator cannot handle This -> Parameter conversion
                        // so we handle it explicitly here in this visitor.
                        replaceThisWithParameter = targetMethod.Parameters[0];
                    }
                }

                if (sourceMethod.Parameters != null && targetMethod.Parameters != null
                    && sourceMethod.Parameters.Count == targetMethod.Parameters.Count)
                {
                    for (int i = 0, n = sourceMethod.Parameters.Count; i < n; i++)
                    {
                        dup.DuplicateFor[sourceMethod.Parameters[i].UniqueKey] = targetMethod.Parameters[i];
                    }
                }

                // This code makes sure that generic method parameters used by contracts inherited from contract class
                // are correctly replaced by the one defined in the target method.
                // Without this mapping <c>CheckPost</c> method in generated async closure class would contain an invalid
                // reference to a generic contract method parameter instead of generic async closure type parameter.
                // For more about this problem see comments for Microsoft.Contracts.Foxtrot.EmitAsyncClosure.GenericTypeMapper class
                // and issue #380.
                if (sourceMethod.TemplateParameters != null && targetMethod.TemplateParameters != null
                    && sourceMethod.TemplateParameters.Count == targetMethod.TemplateParameters.Count)
                {
                    for (int i = 0, n = sourceMethod.TemplateParameters.Count; i < n; i++)
                    {
                        dup.DuplicateFor[sourceMethod.TemplateParameters[i].UniqueKey] = targetMethod.TemplateParameters[i];
                    }
                }
            }

            var originalType = HelperMethods.IsContractTypeForSomeOtherType(sourceMethod.DeclaringType, contractNodes);
            if (originalType != null)
            {
                var contractType = this.contractClass = sourceMethod.DeclaringType;
                while (contractType.Template != null)
                {
                    contractType = contractType.Template;
                }
                    
                while (originalType.Template != null)
                {
                    originalType = originalType.Template;
                }

                // forward ContractType<A,B> -> originalType<A',B'>
                this.contractClassToForward = contractType;
                this.targetTypeToForwardTo = originalType;

                //dup.DuplicateFor[contractType.UniqueKey] = originalType;
            }
        }
예제 #14
0
        public void AddAsyncPost(List<Ensures> asyncPostconditions)
        {
            var origBody = new Block(this.checkBody);
            origBody.HasLocals = true;

            var newBodyBlock = new Block(new StatementList());
            newBodyBlock.HasLocals = true;

            var methodBody = new StatementList();
            var methodBodyBlock = new Block(methodBody);
            methodBodyBlock.HasLocals = true;
            checkMethod.Body = methodBodyBlock;

            methodBody.Add(newBodyBlock);
            Block newExitBlock = new Block();
            methodBody.Add(newExitBlock);

            #region Map closure locals to fields and initialize closure fields

            foreach (Ensures e in asyncPostconditions)
            {
                if (e == null) continue;
                this.Visit(e);
                if (this.forwarder != null) { this.forwarder.Visit(e); }
                ReplaceResult repResult = new ReplaceResult(this.checkMethod, this.originalResultLocal, this.parent.assemblyBeingRewritten);
                repResult.Visit(e);
                // now need to initialize closure result fields
                foreach (var target in repResult.NecessaryResultInitializationAsync(this.closureLocals))
                {
                    // note: target here 
                    methodBody.Add(new AssignmentStatement(target, this.originalResultLocal));
                }
            }

            #endregion

            #region Emit normal postconditions

            SourceContext lastEnsuresSourceContext = default(SourceContext);
            bool hasLastEnsuresContext = false;
            bool containsExceptionalPostconditions = false;
            var ensuresChecks = new StatementList();
            foreach (Ensures e in asyncPostconditions)
            {
                // Exceptional postconditions are handled separately.
                if (e is EnsuresExceptional)
                {
                    containsExceptionalPostconditions = true;
                    continue;
                }

                if (IsVoidTask()) break; // something is wrong in the original contract

                lastEnsuresSourceContext = e.SourceContext;
                hasLastEnsuresContext = true;
                // call Contract.RewriterEnsures
                Method ensMethod = this.parent.runtimeContracts.EnsuresMethod;
                ExpressionList args = new ExpressionList();
                args.Add(e.PostCondition);
                if (e.UserMessage != null)
                    args.Add(e.UserMessage);
                else
                    args.Add(Literal.Null);
                if (e.SourceConditionText != null)
                {
                    args.Add(e.SourceConditionText);
                }
                else
                {
                    args.Add(Literal.Null);
                }
                ensuresChecks.Add(new ExpressionStatement(
                  new MethodCall(new MemberBinding(null, ensMethod),
                  args, NodeType.Call, SystemTypes.Void), e.SourceContext));
            }
            this.parent.cleanUpCodeCoverage.VisitStatementList(ensuresChecks);
            this.parent.EmitRecursionGuardAroundChecks(this.checkMethod, methodBodyBlock, ensuresChecks);
            #endregion Normal postconditions

            #region Exceptional postconditions
            if (containsExceptionalPostconditions)
            {
                // Because async tasks wrap exceptions into Aggregate exceptions, we have to catch AggregateException
                // and iterate over the internal exceptions of the Aggregate.

                // We thus emit the following handler:
                //
                //  catch(AggregateException ae) {
                //    ae.Handle(this.CheckException);
                //    rethrow;
                //  }
                //
                //  alternatively, if the Task has no Result, we emit
                //
                //    var ae = t.Exception as AggregateException;
                //    if (ae != null) {
                //      ae.Handle(this.CheckException);
                //      throw ae;
                //    }

                var aggregateType = AggregateExceptionType.Value;

                var exnParameter = new Parameter(Identifier.For("e"), SystemTypes.Exception);
                this.checkExceptionMethod = new Method(this.closureClass, null, this.checkExceptionMethodId, new ParameterList(exnParameter), SystemTypes.Boolean, new Block(new StatementList()));
                this.checkExceptionMethod.Body.HasLocals = true;
                checkExceptionMethod.CallingConvention = CallingConventionFlags.HasThis;
                checkExceptionMethod.Flags |= MethodFlags.Public;

                this.closureClass.Members.Add(checkExceptionMethod);

                if (this.IsVoidTask())
                {
                    var blockAfterTest = new Block();
                    methodBody.Add(origBody);
                    methodBody.Add(new Branch(new UnaryExpression(this.newResultLocal, NodeType.LogicalNot), blockAfterTest));
                    var funcType = Func2Type.Value;
                    funcType = funcType.GetTemplateInstance(this.parent.assemblyBeingRewritten, SystemTypes.Exception, SystemTypes.Boolean);
                    var handleMethod = aggregateType.GetMethod(Identifier.For("Handle"), funcType);

                    var funcLocal = new Local(funcType);
                    var ldftn = new UnaryExpression(new MemberBinding(null, this.checkExceptionMethod), NodeType.Ldftn, CoreSystemTypes.IntPtr);
                    methodBody.Add(new AssignmentStatement(funcLocal, new Construct(new MemberBinding(null, funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr)), new ExpressionList(this.checkMethod.ThisParameter, ldftn))));
                    methodBody.Add(new ExpressionStatement(new MethodCall(new MemberBinding(this.newResultLocal, handleMethod), new ExpressionList(funcLocal))));
                    methodBody.Add(new Throw(this.newResultLocal));
                    methodBody.Add(blockAfterTest);
                }
                else
                {
                    // The tryCatch holds the try block, the catch blocks, and an empty block that is the
                    // target of an unconditional branch for normal execution to go from the try block
                    // around the catch blocks.
                    if (this.checkMethod.ExceptionHandlers == null) this.checkMethod.ExceptionHandlers = new ExceptionHandlerList();

                    Block afterCatches = new Block(new StatementList());

                    Block tryCatch = newBodyBlock;
                    Block tryBlock = new Block(new StatementList());
                    tryBlock.Statements.Add(origBody);
                    tryBlock.Statements.Add(new Branch(null, afterCatches, false, true, true));
                    // the EH needs to have a pointer to this block so the writer can
                    // calculate the length of the try block. So it should be the *last*
                    // thing in the try body.
                    Block blockAfterTryBody = new Block(null);
                    tryBlock.Statements.Add(blockAfterTryBody);
                    tryCatch.Statements.Add(tryBlock);
                    // The catchBlock contains the catchBody, and then
                    // an empty block that is used in the EH.

                    Block catchBlock = new Block(new StatementList());
                    Local l = new Local(aggregateType);
                    Throw rethrow = new Throw();
                    rethrow.NodeType = NodeType.Rethrow;

                    catchBlock.Statements.Add(new AssignmentStatement(l, new Expression(NodeType.Pop)));

                    var funcType = Func2Type.Value;
                    funcType = funcType.GetTemplateInstance(this.parent.assemblyBeingRewritten, SystemTypes.Exception, SystemTypes.Boolean);
                    var handleMethod = aggregateType.GetMethod(Identifier.For("Handle"), funcType);

                    var funcLocal = new Local(funcType);
                    var ldftn = new UnaryExpression(new MemberBinding(null, this.checkExceptionMethod), NodeType.Ldftn, CoreSystemTypes.IntPtr);
                    catchBlock.Statements.Add(new AssignmentStatement(funcLocal, new Construct(new MemberBinding(null, funcType.GetConstructor(SystemTypes.Object, SystemTypes.IntPtr)), new ExpressionList(this.checkMethod.ThisParameter, ldftn))));
                    catchBlock.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(l, handleMethod), new ExpressionList(funcLocal))));
                    // Handle method should return if all passes
                    catchBlock.Statements.Add(rethrow);
                    // The last thing in each catch block is an empty block that is the target of
                    // BlockAfterHandlerEnd in each exception handler.
                    // It is used in the writer to determine the length of each catch block
                    // so it should be the last thing added to each catch block.
                    Block blockAfterHandlerEnd = new Block(new StatementList());
                    catchBlock.Statements.Add(blockAfterHandlerEnd);
                    tryCatch.Statements.Add(catchBlock);

                    // add information to the ExceptionHandlers of this method
                    ExceptionHandler exHandler = new ExceptionHandler();
                    exHandler.TryStartBlock = origBody;
                    exHandler.BlockAfterTryEnd = blockAfterTryBody;
                    exHandler.HandlerStartBlock = catchBlock;
                    exHandler.BlockAfterHandlerEnd = blockAfterHandlerEnd;
                    exHandler.FilterType = l.Type;
                    exHandler.HandlerType = NodeType.Catch;
                    this.checkMethod.ExceptionHandlers.Add(exHandler);

                    tryCatch.Statements.Add(afterCatches);
                }
                EmitCheckExceptionBody(asyncPostconditions);
            }
            else // no exceptional post conditions
            {
                newBodyBlock.Statements.Add(origBody);
            }
            #endregion Exceptional and finally postconditions


            #region Create a block for the return statement and insert it
            // this is the block that contains the return statements
            // it is (supposed to be) the single exit from the method
            // that way, anything that must always be done can be done
            // in this block
            Statement returnStatement;
            if (this.IsVoidTask())
            {
                returnStatement = new Return();
            }
            else
            {
                returnStatement = new Return(this.newResultLocal);
            }
            if (hasLastEnsuresContext)
            {
                returnStatement.SourceContext = lastEnsuresSourceContext;
            }
            Block returnBlock = new Block(new StatementList(1));
            returnBlock.Statements.Add(returnStatement);
            methodBody.Add(returnBlock);
            #endregion
        }
예제 #15
0
 /// <summary>
 /// Checks whether a specific parameter is an "out" parameter.
 /// </summary>
 /// <param name="parameter">Parameter to test.</param>
 /// <returns>True if "out" parameter.</returns>
 public static bool IsOut(Parameter parameter)
 {
   return (parameter.Flags & ParameterFlags.Out) > 0 && (parameter.Flags & ParameterFlags.In) == 0;
 }
예제 #16
0
파일: Error.cs 프로젝트: hesam/SketchSharp
 public static string GetParameterTypeName(Parameter parameter, MemberNameOptions givenOptions, Scope scope) {
   if (parameter == null) return "";
   Reference r = parameter.Type as Reference;
   TypeNode typeNode = null;
   StringBuilder sb = new StringBuilder();
   string backUpName = null;
   if (r != null) {
     if ((parameter.Flags & ParameterFlags.Out) != 0) {
       if ( IsOptionActive(givenOptions, MemberNameOptions.PutParameterModifiers) ) sb.Append("out ");
       typeNode = r.ElementType;
     } else {
       if (IsOptionActive(givenOptions, MemberNameOptions.PutParameterModifiers)) sb.Append("ref ");
       typeNode = r.ElementType;
     }
   } else if (parameter.GetParamArrayElementType() != null) {
     if (IsOptionActive(givenOptions, MemberNameOptions.PutParameterModifiers)) sb.Append("params ");
     typeNode = parameter.Type;
   } else {
     typeNode = parameter.Type;
     if (typeNode == null && parameter.TypeExpression != null)
         backUpName = parameter.TypeExpression.SourceContext.SourceText;
   }
   sb.Append(backUpName != null ? MemberNameBuilder.GetAtPrefixedIfRequired(backUpName, givenOptions) : GetMemberNameRaw(typeNode, givenOptions, scope));
   if (IsOptionActive(givenOptions, MemberNameOptions.PutParameterName) && parameter.Name!= null) {
     sb.Append(' ');
     sb.Append(MemberNameBuilder.GetAtPrefixedIfRequired(parameter.Name.ToString(), givenOptions));
   }
   return sb.ToString();
 }
예제 #17
0
 public override Expression VisitParameter(Parameter parameter)
 {
     if (parameter == null) return null;
     Parameter dup = (Parameter)this.DuplicateFor[parameter.UniqueKey];
     if (dup != null)
     {
         if (dup.DeclaringMethod == null) dup.DeclaringMethod = this.TargetMethod;
         return dup;
     }
     this.DuplicateFor[parameter.UniqueKey] = dup = (Parameter)parameter.Clone();
     if (dup.MarshallingInformation != null)
         dup.MarshallingInformation = dup.MarshallingInformation.Clone();
     dup.DeclaringMethod = this.TargetMethod;
     return base.VisitParameter(dup);
 }
예제 #18
0
파일: Error.cs 프로젝트: hesam/SketchSharp
 public override string GetParameterSignature(ParameterField f){
   if (f == null) return "";
   StringBuilder result = new StringBuilder("(parameter) "); //REVIEW: localize the (parameter) part?
   this.currentParameter = f.Parameter;
   result.Append(this.GetTypeName(f.Type)+" "+f.Name.ToString()); 
   return result.ToString();
 }
예제 #19
0
 public override Expression VisitParameter(Parameter parameter)
 {
     Parameter result = (Parameter)base.VisitParameter(parameter);
     Reference pRefType = result.Type as Reference;
     return result;
 }
예제 #20
0
    private Expression ParsePrimaryExpression(TokenSet followers){
      Expression expression = null;
      SourceContext sctx = this.scanner.CurrentSourceContext;
      switch(this.currentToken){
        case Token.ArgList:
          this.GetNextToken();
          expression = new ArglistExpression(sctx);
          break;
        case Token.Delegate:{
          this.GetNextToken();
          ParameterList parameters = null;
          if (this.currentToken == Token.LeftParenthesis)
            parameters = this.ParseParameters(Token.RightParenthesis, followers|Token.LeftBrace);
          Block block = null;
          if (this.currentToken == Token.LeftBrace)
            block = this.ParseBlock(this.scanner.CurrentSourceContext, followers);
          else
            this.SkipTo(followers, Error.ExpectedLeftBrace);
          sctx.EndPos = this.scanner.endPos;
          return new AnonymousNestedDelegate(parameters, block, sctx);}
        case Token.New:
          expression = this.ParseNew(followers|Token.Dot|Token.LeftBracket|Token.Arrow);
          break;
        case Token.Identifier:
          expression = this.scanner.GetIdentifier();
          if (this.sink != null) {
            this.sink.StartName((Identifier)expression);
          }
          this.GetNextToken();
          if (this.currentToken == Token.DoubleColon){
            this.GetNextToken();
            Identifier id = this.scanner.GetIdentifier();
            id.Prefix = (Identifier)expression;
            id.SourceContext.StartPos = expression.SourceContext.StartPos;
            expression = id;
            if (this.currentToken != Token.EndOfFile)
              this.GetNextToken();
          }else if (this.currentToken == Token.Lambda){
            Parameter par = new Parameter((Identifier)expression, null);
            par.SourceContext = expression.SourceContext;
            return this.ParseLambdaExpression(par.SourceContext, new ParameterList(par), followers);
          }
          break;
        case Token.Null:
          expression = new Literal(null, null, sctx);
          this.GetNextToken();
          break;
        case Token.True:
          expression = new Literal(true, null, sctx);
          this.GetNextToken();
          break;
        case Token.False:
          expression = new Literal(false, null, sctx);
          this.GetNextToken();
          break;
        case Token.CharLiteral:
          expression = new Literal(this.scanner.charLiteralValue, null, sctx);
          this.GetNextToken();
          break;
        case Token.HexLiteral:
          expression = this.ParseHexLiteral();
          break;
        case Token.IntegerLiteral:
          expression = this.ParseIntegerLiteral();
          break;
        case Token.RealLiteral:
          expression = this.ParseRealLiteral();
          break;
        case Token.StringLiteral:
          expression = this.scanner.GetStringLiteral();
          this.GetNextToken();
          break;
        case Token.This:
          expression = new This(sctx, false);
          if (this.sink != null) {
            this.sink.StartName(expression);
          }
          this.GetNextToken();
          if (this.currentToken == Token.LeftParenthesis
            && (this.inInstanceConstructor==BaseOrThisCallKind.None
            || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyThisSeen)){
            QualifiedIdentifier thisCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext);
            MethodCall thisConstructorCall = new MethodCall(thisCons, null, NodeType.Call);
            thisConstructorCall.SourceContext = sctx;
            SourceContext lpCtx = this.scanner.CurrentSourceContext;
            this.Skip(Token.LeftParenthesis);
            thisConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out thisConstructorCall.SourceContext.EndPos);
            expression = thisConstructorCall;
            this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyThisSeen;
            goto done;
          }
          break;
        case Token.Base:
          Base ba = new Base(sctx, false);
          expression = ba;
          if (this.sink != null) {
            this.sink.StartName(expression);
          }
          this.GetNextToken();
          if (this.currentToken == Token.Semicolon &&
            (this.inInstanceConstructor == BaseOrThisCallKind.ColonThisOrBaseSeen
            || this.inInstanceConstructor == BaseOrThisCallKind.None)) {
            // When there are non-null fields, then the base ctor call can happen only after they are
            // initialized.
            // In Spec#, we allow a base ctor call in the body of the ctor. But if someone is using
            // the C# comment convention, then they cannot do that.
            // So allow "base;" as a marker to indicate where the base ctor call should happen.
            // There may be an explicit "colon base call" or it may be implicit.
            //
            // Just leave expression as a bare "Base" node; later pipeline stages will all have
            // to ignore it. Mark the current ctor as having (at least) one of these bad boys
            // in it.
            ba.UsedAsMarker = true;
            this.currentCtor.ContainsBaseMarkerBecauseOfNonNullFields = true;
            goto done;
          }
          if (this.currentToken == Token.LeftParenthesis
            && (this.inInstanceConstructor==BaseOrThisCallKind.None
              || this.inInstanceConstructor==BaseOrThisCallKind.InCtorBodyBaseSeen)){
            QualifiedIdentifier supCons = new QualifiedIdentifier(expression, StandardIds.Ctor, this.scanner.CurrentSourceContext);
            MethodCall superConstructorCall = new MethodCall(supCons, null, NodeType.Call);
            superConstructorCall.SourceContext = sctx;
            SourceContext lpCtx = this.scanner.CurrentSourceContext;
            this.Skip(Token.LeftParenthesis);
            superConstructorCall.Operands = this.ParseArgumentList(followers|Token.LeftBrace|Token.Semicolon, lpCtx, out superConstructorCall.SourceContext.EndPos);
            expression = superConstructorCall;
            this.inInstanceConstructor=BaseOrThisCallKind.InCtorBodyBaseSeen;
            goto done;
          }
          break;
        case Token.Typeof:
        case Token.Sizeof:
        case Token.Default:{
          //if (this.currentToken == Token.Sizeof && !this.inUnsafeCode)
            //this.HandleError(Error.SizeofUnsafe);
          UnaryExpression uex = new UnaryExpression(null,
            this.currentToken == Token.Typeof ? NodeType.Typeof : this.currentToken == Token.Sizeof ? NodeType.Sizeof : NodeType.DefaultValue);
          uex.SourceContext = sctx;
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          TypeNode t = null;
          if (this.currentToken == Token.Void && uex.NodeType == NodeType.Typeof){
            t = this.TypeExpressionFor(Token.Void); this.GetNextToken();
          }else
            t = this.ParseTypeExpression(null, followers|Token.RightParenthesis, false, false, uex.NodeType == NodeType.Typeof);
          if (t == null){this.SkipTo(followers); return null;}
          uex.Operand = new MemberBinding(null, t, t.SourceContext, null);
          uex.Operand.SourceContext = t.SourceContext;
          uex.SourceContext.EndPos = this.scanner.endPos;
          this.Skip(Token.RightParenthesis);
          expression = uex;
          break;}
        case Token.Stackalloc:{
          this.GetNextToken();
          TypeNode elementType = this.ParseBaseTypeExpression(null, followers|Token.LeftBracket, false, false);
          if (elementType == null){this.SkipTo(followers); return null;}
          Token openingDelimiter = this.currentToken;
          if (this.currentToken != Token.LeftBracket){
            this.HandleError(Error.BadStackAllocExpr);
            if (this.currentToken == Token.LeftParenthesis) this.GetNextToken();
          }else
            this.GetNextToken();
          Expression numElements = this.ParseExpression(followers|Token.RightBracket|Token.RightParenthesis);
          sctx.EndPos = this.scanner.endPos;
          if (this.currentToken == Token.RightParenthesis && openingDelimiter == Token.LeftParenthesis)
            this.GetNextToken();
          else
            this.Skip(Token.RightBracket);
          this.SkipTo(followers);
          return new StackAlloc(elementType, numElements, sctx);}
        case Token.Checked:
        case Token.Unchecked:
          //TODO: use NodeType.SkipCheck and NodeType.EnforceCheck
          Block b = new Block(new StatementList(1), this.currentToken == Token.Checked, this.currentToken == Token.Unchecked, this.inUnsafeCode);
          b.SourceContext = sctx;
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          b.Statements.Add(new ExpressionStatement(this.ParseExpression(followers|Token.RightParenthesis)));
          this.Skip(Token.RightParenthesis);
          expression = new BlockExpression(b);
          expression.SourceContext = b.SourceContext;
          break;
        case Token.RefType:{
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          Expression e = this.ParseExpression(followers|Token.RightParenthesis);
          this.Skip(Token.RightParenthesis);
          expression = new RefTypeExpression(e, sctx);
          break;
        }
        case Token.RefValue:{
          this.GetNextToken();
          this.Skip(Token.LeftParenthesis);
          Expression e = this.ParseExpression(followers|Token.Comma);
          this.Skip(Token.Comma);
          TypeNode te = this.ParseTypeOrFunctionTypeExpression(followers|Token.RightParenthesis, false, true);
          Expression operand2 = new MemberBinding(null, te);
          if (te is TypeExpression)
            operand2.SourceContext = te.SourceContext;
          else
            operand2.SourceContext = sctx;
          this.Skip(Token.RightParenthesis);
          expression = new RefValueExpression(e, operand2, sctx);
          break;
        }
        case Token.Bool:
        case Token.Decimal:
        case Token.Sbyte:
        case Token.Byte:
        case Token.Short:
        case Token.Ushort:
        case Token.Int:
        case Token.Uint:
        case Token.Long:
        case Token.Ulong:
        case Token.Char:
        case Token.Float:
        case Token.Double:
        case Token.Object:
        case Token.String:
          MemberBinding mb = new MemberBinding(null, this.TypeExpressionFor(this.currentToken), sctx);
          this.GetNextToken();
          expression = this.ParseIndexerCallOrSelector(mb, followers);
          goto done;
        case Token.LeftParenthesis:
          expression = this.ParseParenthesizedExpression(followers|Token.Dot|Token.LeftBracket|Token.Arrow, true);
          break;
        default:
          if (Parser.IdentifierOrNonReservedKeyword[this.currentToken]) goto case Token.Identifier;
          if (Parser.InfixOperators[this.currentToken]){
            this.HandleError(Error.InvalidExprTerm, this.scanner.GetTokenSource());
            this.GetNextToken();
          }else
            this.SkipTo(followers|Parser.PrimaryStart, Error.InvalidExprTerm, this.scanner.GetTokenSource());
          if (Parser.PrimaryStart[this.currentToken]) return this.ParsePrimaryExpression(followers);
          goto done;
      }
      if (expression is Base && this.currentToken != Token.Dot && this.currentToken != Token.LeftBracket){
        this.HandleError(expression.SourceContext, Error.BaseIllegal);
        expression = null;
      }

      expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne);
      for(;;){
        switch(this.currentToken){
          case Token.AddOne:
          case Token.SubtractOne:
            SourceContext ctx = expression.SourceContext;
            ctx.EndPos = this.scanner.endPos;
            PostfixExpression pex = new PostfixExpression(expression, Parser.ConvertToBinaryNodeType(this.currentToken), ctx);
            this.GetNextToken();
            expression = pex;
            break;
          case Token.Dot:
            expression = this.ParseIndexerCallOrSelector(expression, followers|Token.AddOne|Token.SubtractOne);
            break;
          default:
            goto done;
        }
      }
      done:
        this.SkipTo(followers);
      return expression;
    }
예제 #21
0
    private Method MakeTriggerFailureMethod(bool throwOnFailure)
    {
      Parameter kindParameter = new Parameter(Identifier.For("kind"), contractNodes.ContractFailureKind);
      Parameter messageParameter = new Parameter(Identifier.For("msg"), SystemTypes.String);
      Parameter userMessageParameter = new Parameter(Identifier.For("userMessage"), SystemTypes.String);
      Parameter conditionTextParameter = new Parameter(Identifier.For("conditionTxt"), SystemTypes.String);
      Parameter exceptionParameter = new Parameter(Identifier.For("inner"), SystemTypes.Exception);
      ParameterList pl = new ParameterList(kindParameter, messageParameter, userMessageParameter, conditionTextParameter, exceptionParameter);

      Block body = new Block(new StatementList());
      Method m = new Method(this.RuntimeContractType, null, ContractNodes.TriggerFailureName, pl, SystemTypes.Void, body);
      m.Flags = MethodFlags.Assembly | MethodFlags.Static;
      m.Attributes = new AttributeList();
      this.RuntimeContractType.Members.Add(m);

      //
      // Generate the following
      //
      // #if throwOnFailure
      // throw new ContractException(kind, message, userMessage, conditionText, inner);
      // #else
      // Debug.Assert(false, messageParameter);
      // #endif

      if (throwOnFailure)
      {
        ExpressionList elist = new ExpressionList();
        elist.Add(kindParameter);
        elist.Add(messageParameter);
        elist.Add(userMessageParameter);
        elist.Add(conditionTextParameter);
        elist.Add(exceptionParameter);
        body.Statements.Add(new Throw(new Construct(new MemberBinding(null, this.ContractExceptionCtor), elist)));
      }
      else
      {
        var sysassem = SystemTypes.SystemDllAssembly;
        if (sysassem == null) {
          throw new ApplicationException("Cannot find System.dll");
        }
        var debugType = sysassem.GetType(Identifier.For("System.Diagnostics"), Identifier.For("Debug"));
        if (debugType == null)
        {
          throw new ApplicationException("Cannot find System.Diagnostics.Debug");
        }
        var assertMethod = debugType.GetMethod(Identifier.For("Assert"), SystemTypes.Boolean, SystemTypes.String);
        if (assertMethod == null)
        {
          throw new ApplicationException("Cannot find System.Diagnostics.Debug.Assert(bool,string)");
        }
        ExpressionList elist = new ExpressionList();
        elist.Add(Literal.False);
        elist.Add(messageParameter);
        body.Statements.Add(new ExpressionStatement(new MethodCall(new MemberBinding(null, assertMethod), elist)));
        body.Statements.Add(new Return());
      }

      return m;
    }
예제 #22
0
 public override AttributeNode VisitParameterAttribute(AttributeNode attr, Parameter parameter) {
   attr = base.VisitParameterAttribute(attr, parameter);
   if (attr == null) return null;
   if (attr.Type == SystemTypes.ParamArrayAttribute && attr.SourceContext.Document != null)
     this.HandleError(attr, Error.ExplicitParamArray, this.GetTypeName(SystemTypes.ParamArrayAttribute));
   if ((IsAdditive(attr) || IsInside(attr) || attr.Type == SystemTypes.CapturedAttribute || attr.Type == SystemTypes.NoDefaultContractAttribute)
       && parameter.Type != null && parameter.Type.IsValueType) {
     this.HandleError(attr, Error.AttributeAllowedOnlyOnReferenceTypeParameters, this.GetTypeName(attr.Type));
   }
   if (attr.Type == SystemTypes.CapturedAttribute && parameter.IsOut) {
     this.HandleError(attr, Error.AttributeNotAllowedOnlyOnInParameters, this.GetTypeName(attr.Type));
   }
   return attr;
 }
예제 #23
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);
        }
예제 #24
0
 private ParameterList ParseParameters(Token closingToken, TokenSet followers, bool namesAreOptional, bool typesAreOptional){
   bool arglist = false;
   Debug.Assert(closingToken == Token.RightParenthesis || closingToken == Token.RightBracket);
   SourceContext sctx = this.scanner.CurrentSourceContext;
   if (closingToken == Token.RightParenthesis){
     if (this.currentToken != Token.LeftParenthesis){
       this.SkipTo(followers|Parser.UnaryStart, Error.SyntaxError, "(");
     }
     if (this.currentToken == Token.LeftParenthesis)
       this.GetNextToken();
   }else{
     if (this.currentToken != Token.LeftBracket)
       this.SkipTo(followers|Parser.UnaryStart, Error.SyntaxError, "[");
     if (this.currentToken == Token.LeftBracket)
       this.GetNextToken();
   }
   ParameterList result = new ParameterList();
   if (this.currentToken != closingToken && this.currentToken != Token.EndOfFile){
     bool allowRefParameters = closingToken == Token.RightParenthesis;
     TokenSet followersOrCommaOrRightParenthesis = followers|Token.Comma|closingToken|Token.ArgList;
     int counter = 0;
     for (;;){
       if (this.currentToken == Token.ArgList) {
         Parameter ap = new Parameter(StandardIds.__Arglist, this.TypeExpressionFor(Token.Void));
         ap.SourceContext = this.scanner.CurrentSourceContext;
         this.GetNextToken();
         arglist = true;
         result.Add(ap);
         break;
       }
       Parameter p = this.ParseParameter(followersOrCommaOrRightParenthesis, allowRefParameters, namesAreOptional, typesAreOptional);
       if (namesAreOptional && p != null && p.Name == Identifier.Empty){
         p.Name = new Identifier("p"+counter++);
         if (p.Type != null)
           p.Name.SourceContext = p.Type.SourceContext;
       }
       if (typesAreOptional && p != null && p.Type == null) allowRefParameters = false;
       result.Add(p);
       if (this.currentToken == Token.Comma)
         this.GetNextToken();
       else
         break;
     }
   }
   if (closingToken == Token.RightBracket) {
     if (result.Count == 0)
       this.HandleError(Error.IndexerNeedsParam);
     else if (arglist) {
       this.HandleError(result[result.Count-1].SourceContext, Error.NoArglistInIndexers);
       result.Count = result.Count-1;
     }
   }
   if (this.currentToken == closingToken){
     if (this.sink != null)
       this.sink.MatchPair(sctx, this.scanner.CurrentSourceContext);
     this.GetNextToken();
     this.SkipTo(followers);
   }else{
     this.SkipTo(followers, closingToken==Token.RightBracket ? Error.ExpectedRightBracket : Error.ExpectedRightParenthesis);
   }
   return result;
 }
예제 #25
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;
    }
예제 #26
0
        private static bool FieldAssociatedWithParameter(Field field, Method originalMethod, out Parameter p)
        {
            string fname = field.Name.Name;

            if (fname.EndsWith("__this"))
            {
                // check that it is not a nested one
                if (fname.Length > 8 && !fname.Substring(2, fname.Length - 8).Contains("__"))
                {
                    p = originalMethod.ThisParameter;
                    return true;
                }
            }

            foreach (Parameter par in originalMethod.Parameters)
            {
                string pname = par.Name.Name;
                if (fname == pname)
                {
                    p = par;
                    return true;
                }
            }

            p = null;
            return false;
        }
예제 #27
0
        public virtual Expression VisitParameter(Parameter parameter)
        {
            if (parameter == null) return null;
            parameter.Attributes = this.VisitAttributeList(parameter.Attributes);
            parameter.Type = this.VisitTypeReference(parameter.Type);
            parameter.DefaultValue = this.VisitExpression(parameter.DefaultValue);
            ParameterBinding pb = parameter as ParameterBinding;

            if (pb != null)
            {
                Parameter par = this.VisitParameter(pb.BoundParameter) as Parameter;
                if (par != null)
                    pb.BoundParameter = par;
            }

            return parameter;
        }
예제 #28
0
 public override Expression CoerceArgument(Expression argument, Parameter parameter) {
   Expression result = base.CoerceArgument(argument, parameter);
   if (result != null) {
     Reference r = parameter.Type as Reference;
     if (r != null) {
       UnaryExpression unexp = argument as UnaryExpression;
       if (parameter.IsOut) {
         if (unexp == null) {
           if (argument.SourceContext.Document != null)
             this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r));
         } else {
           if (unexp.NodeType == NodeType.RefAddress)
             this.HandleError(argument, Error.NoImplicitConversion, "ref " + this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r));
           else if (unexp.NodeType != NodeType.OutAddress)
             this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r));
         }
       } else {
         if (unexp == null) {
           if (argument.SourceContext.Document != null)
             this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r));
         } else {
           if (unexp.NodeType == NodeType.OutAddress)
             this.HandleError(argument, Error.NoImplicitConversion, "out " + this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r));
           else if (unexp.NodeType != NodeType.RefAddress)
             this.HandleError(argument, Error.NoImplicitConversion, this.typeSystem.GetTypeName(r.ElementType), this.typeSystem.GetTypeName(r));
         }
       }
     } else if (!(parameter.Type is Reference)) {
       if (argument.NodeType == NodeType.OutAddress)
         this.HandleError(((UnaryExpression)argument).Operand, Error.BadArgExtraRef, (parameter.ParameterListIndex + 1).ToString(), "out");
       else if (argument.NodeType == NodeType.RefAddress)
         this.HandleError(((UnaryExpression)argument).Operand, Error.BadArgExtraRef, (parameter.ParameterListIndex + 1).ToString(), "ref");
     }
   }
   // Special case to handle arglist when the parameter is a params object[]
   // and the argument constains __arglist(). We will flatten that __arglist. 
   // This is an effort to simulate CSC. 
   // Note, if passing an __arglist and an object for params object[], CSC generates
   // invalid code while we are ok. See SingSharpConformance.Suite. 
   TypeNode maybeObjectType = parameter.GetParamArrayElementType();
   if (maybeObjectType == SystemTypes.Object) {
     result = FlattenArglist(result);
   }
   return result;
 }
예제 #29
0
 public override Expression VisitParameter(Parameter parameter)
 {
     if (parameter == null) return null;
     Write("{0}", GetParameterDirection(parameter.Flags));
     this.VisitTypeReference(parameter.Type);
     Write(" ");
     if (parameter.DefaultValue != null)
         throw new ArgumentException("Unexpected parameter default value");
     Write("{0}", parameter.Name.Name);
     return parameter;
 }
        private static TypeNode IsConstrainedTypeVariable(Parameter target)
        {
            if (target == null) return null;

            Reference r = target.Type as Reference;
                
            if (r == null) return null;
                
            if (!(r.ElementType is ITypeParameter)) return null;
                
            return r.ElementType;
        }