示例#1
0
        private TypeNode ConvertToClassParameter(TypeNode baseType, TypeNode/*!*/ typeParameter)
        {
            ClassParameter result;
            if (typeParameter is MethodTypeParameter)
            {
                result = new MethodClassParameter();
            }
            else if (typeParameter is TypeParameter)
            {
                result = new ClassParameter();
                result.DeclaringType = typeParameter.DeclaringType;
            }
            else
                return typeParameter; //give up
            result.SourceContext = typeParameter.SourceContext;
            result.TypeParameterFlags = ((ITypeParameter)typeParameter).TypeParameterFlags;

            result.Name = typeParameter.Name;
            result.Namespace = StandardIds.ClassParameter;
            result.BaseClass = baseType is Class ? (Class)baseType : CoreSystemTypes.Object;
            result.DeclaringMember = ((ITypeParameter)typeParameter).DeclaringMember;
            result.DeclaringModule = typeParameter.DeclaringModule;
            result.Flags = typeParameter.Flags & ~TypeFlags.Interface;
            //InterfaceList constraints = result.Interfaces = new InterfaceList();
            InterfaceList interfaces = typeParameter.Interfaces;
            for (int i = 1, n = interfaces == null ? 0 : interfaces.Count; i < n; i++)
            {
                //^ assert interfaces != null;
                interfaces.Add(this.VisitInterfaceReference(interfaces[i]));
            }
            return result;
        }
示例#2
0
    private Method CreateWrapperMethod(bool virtcall, TypeNode virtcallConstraint, Method templateMethod, TypeNode templateType, TypeNode wrapperType, Method methodWithContract, Method instanceMethod, SourceContext callingContext)
    {
      bool isProtected = IsProtected(templateMethod);
      Identifier name = templateMethod.Name;
      if (virtcall) {
        if (virtcallConstraint != null) {
          name = Identifier.For("CV$" + name.Name);
        }
        else {
          name = Identifier.For("V$" + name.Name);
        }
      }
      else {
        name = Identifier.For("NV$" + name.Name);
      }
      Duplicator dup = new Duplicator(this.assemblyBeingRewritten, wrapperType);
      TypeNodeList typeParameters = null;
      TypeNodeList typeParameterFormals = new TypeNodeList();
      TypeNodeList typeParameterActuals = new TypeNodeList();

      if (templateMethod.TemplateParameters != null) {
        dup.FindTypesToBeDuplicated(templateMethod.TemplateParameters);
        typeParameters = dup.VisitTypeParameterList(templateMethod.TemplateParameters);
        for (int i = 0; i < typeParameters.Count; i++) {
          typeParameterFormals.Add(typeParameters[i]);
          typeParameterActuals.Add(templateMethod.TemplateParameters[i]);
        }
      }
      ITypeParameter constraintTypeParam = null;
      if (virtcallConstraint != null) {
        if (typeParameters == null) { typeParameters = new TypeNodeList(); }
        var constraint = templateMethod.DeclaringType;
        var classConstraint = constraint as Class;
        if (classConstraint != null) {
          var classParam = new MethodClassParameter();
          classParam.BaseClass = classConstraint;
          classParam.Name = Identifier.For("TC");
          classParam.DeclaringType = wrapperType;
          typeParameters.Add(classParam);
          constraintTypeParam = classParam;
        }
        else {
          var mtp = new MethodTypeParameter();
          Interface intf = constraint as Interface;
          if (intf != null) {
            mtp.Interfaces.Add(intf);
          }
          mtp.Name = Identifier.For("TC");
          mtp.DeclaringType = wrapperType;
          typeParameters.Add(mtp);
          constraintTypeParam = mtp;
        }
      }
      var consolidatedTemplateTypeParameters = templateType.ConsolidatedTemplateParameters;
      if (consolidatedTemplateTypeParameters != null && consolidatedTemplateTypeParameters.Count > 0) {
        var consolidatedWrapperTypeParameters = wrapperType.ConsolidatedTemplateParameters;
        for (int i = 0; i < consolidatedTemplateTypeParameters.Count; i++) {
          typeParameterFormals.Add(consolidatedWrapperTypeParameters[i]);
          typeParameterActuals.Add(consolidatedTemplateTypeParameters[i]);
        }
      }
      Specializer spec = null;
      if (typeParameterActuals.Count > 0) {
        spec = new Specializer(this.assemblyBeingRewritten, typeParameterActuals, typeParameterFormals);
      }
      var parameters = new ParameterList();
      var asTypeConstraintTypeParam = constraintTypeParam as TypeNode;

      if (!isProtected && !templateMethod.IsStatic) {
        TypeNode thisType = GetThisTypeInstance(templateType, wrapperType, asTypeConstraintTypeParam);
        parameters.Add(new Parameter(Identifier.For("@this"), thisType));
      }
      for (int i = 0; i < templateMethod.Parameters.Count; i++) {
        parameters.Add((Parameter)dup.VisitParameter(templateMethod.Parameters[i]));
      }
      var retType = dup.VisitTypeReference(templateMethod.ReturnType);
      if (spec != null) {
        parameters = spec.VisitParameterList(parameters);
        retType = spec.VisitTypeReference(retType);
      }

      var wrapperMethod = new Method(wrapperType, null, name, parameters, retType, null);
      RewriteHelper.TryAddCompilerGeneratedAttribute(wrapperMethod);

      if (isProtected) {
        wrapperMethod.Flags = templateMethod.Flags & ~MethodFlags.Abstract;
        wrapperMethod.CallingConvention = templateMethod.CallingConvention;
      }
      else {
        wrapperMethod.Flags |= MethodFlags.Static | MethodFlags.Assembly;
      }
      if (constraintTypeParam != null) {
        constraintTypeParam.DeclaringMember = wrapperMethod;
      }
      if (typeParameters != null) {
        if (spec != null) {
          typeParameters = spec.VisitTypeParameterList(typeParameters);
        }
        wrapperMethod.IsGeneric = true;
        wrapperMethod.TemplateParameters = typeParameters;
      }

      // create body
      var sl = new StatementList();
      Block b = new Block(sl);

      // insert requires
      AddRequiresToWrapperMethod(wrapperMethod, b, methodWithContract);

      // create original call
      var targetType = templateType;
      if (isProtected)
      {
        // need to use base chain instantiation of target type.
        targetType = instanceMethod.DeclaringType;
      }
      else
      {
        if (targetType.ConsolidatedTemplateParameters != null && targetType.ConsolidatedTemplateParameters.Count > 0)
        {
          // need selfinstantiation
          targetType = targetType.GetGenericTemplateInstance(this.assemblyBeingRewritten, wrapperType.ConsolidatedTemplateParameters);
        }
      }
      Method targetMethod = GetMatchingMethod(targetType, templateMethod, wrapperMethod);
      if (targetMethod.IsGeneric) {
        if (typeParameters.Count > targetMethod.TemplateParameters.Count) {
          // omit the extra constrained type arg.
          TypeNodeList origArgs = new TypeNodeList();
          for (int i = 0; i < targetMethod.TemplateParameters.Count; i++) {
            origArgs.Add(typeParameters[i]);
          }
          targetMethod = targetMethod.GetTemplateInstance(wrapperType, origArgs);
        }
        else {
          targetMethod = targetMethod.GetTemplateInstance(wrapperType, typeParameters);
        }
      }
      MethodCall call;
      NodeType callType = virtcall ? NodeType.Callvirt : NodeType.Call;
      if (isProtected) {
        var mb = new MemberBinding(wrapperMethod.ThisParameter, targetMethod);
        var elist = new ExpressionList(wrapperMethod.Parameters.Count);
        for (int i = 0; i < wrapperMethod.Parameters.Count; i++) {
          elist.Add(wrapperMethod.Parameters[i]);
        }
        call = new MethodCall(mb, elist, callType);
      }
      else if (templateMethod.IsStatic) {
        var elist = new ExpressionList(wrapperMethod.Parameters.Count);
        for (int i = 0; i < wrapperMethod.Parameters.Count; i++) {
          elist.Add(wrapperMethod.Parameters[i]);
        }
        call = new MethodCall(new MemberBinding(null, targetMethod), elist, callType);
      }
      else {
        var mb = new MemberBinding(wrapperMethod.Parameters[0], targetMethod);
        var elist = new ExpressionList(wrapperMethod.Parameters.Count - 1);
        for (int i = 1; i < wrapperMethod.Parameters.Count; i++) {
          elist.Add(wrapperMethod.Parameters[i]);
        }
        call = new MethodCall(mb, elist, callType);
      }
      if (constraintTypeParam != null) {
        call.Constraint = asTypeConstraintTypeParam;
      }
      if (HelperMethods.IsVoidType(templateMethod.ReturnType)) {
        sl.Add(new ExpressionStatement(call,callingContext));
        sl.Add(new Return(callingContext));
      }
      else {
        sl.Add(new Return(call,callingContext));
      }
      wrapperMethod.Body = b;

      wrapperType.Members.Add(wrapperMethod);
      return wrapperMethod;
    }
示例#3
0
        private static TypeNode NewEqualMethodTypeParameter(ITypeParameter itp, Method declaringMethod, int index)
        {
            TypeNode declaringType = declaringMethod.DeclaringType;
            ClassParameter cp = itp as ClassParameter;
            if (cp != null)
            {
                MethodClassParameter mcp = new MethodClassParameter();

                mcp.Interfaces = cp.Interfaces.Clone();
                mcp.BaseClass = cp.BaseClass;
                
                mcp.TypeParameterFlags = cp.TypeParameterFlags & ~TypeParameterFlags.VarianceMask;
                mcp.DeclaringType = declaringType;
                mcp.DeclaringModule = declaringType.DeclaringModule;
                
                mcp.Name = cp.Name;
                mcp.ParameterListIndex = index;
                mcp.DeclaringMember = declaringMethod;

                return mcp;
            }

            TypeParameter tp = itp as TypeParameter;
            if (tp != null)
            {
                MethodTypeParameter mp = new MethodTypeParameter();

                mp.Interfaces = tp.Interfaces.Clone();
                
                mp.TypeParameterFlags = tp.TypeParameterFlags & ~TypeParameterFlags.VarianceMask;
                
                mp.DeclaringType = declaringType;
                mp.DeclaringModule = declaringType.DeclaringModule;
                
                mp.Name = tp.Name;
                mp.ParameterListIndex = index;
                mp.DeclaringMember = declaringMethod;

                return mp;
            }

            throw new NotImplementedException("unexpected type parameter kind");
        }
示例#4
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;
    }