コード例 #1
0
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();

            var funcT = SharpMockTypes.Functions[0];
            var funcActualT = new GenericTypeInstanceReference();
            funcActualT.GenericType = funcT;
            funcActualT.GenericArguments.Add(field.Type);

            var accessor = new AnonymousDelegate();
            accessor.Type = funcActualT;
            accessor.ReturnType = field.Type;
            accessor.CallingConvention = CallingConvention.HasThis;

            var accessorBody = new BlockStatement();
            var returnActualField = new ReturnStatement();
            var actualField = new BoundExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            returnActualField.Expression = actualField;
            accessorBody.Statements.Add(returnActualField);
            accessor.Body = accessorBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", funcActualT).As(accessor)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(
                Declare.Variable("interceptionResult", field.Type).As(
                    ChangeType.Convert(Call.PropertyGetter<object>("Return").On("invocation")).To(field.Type))
            );

            Context.Block.Statements.Add(Return.Variable(Locals["interceptionResult"]));
        }
コード例 #2
0
    /// <summary>
    /// Returns a reference to the closure method. If the method is generic, the reference is to an instantiation, 
    /// using the generic parameters of the current class as arguments.
    /// </summary>
    private IMethodReference CreateClosureMethod(AnonymousDelegate anonymousDelegate) {
      bool isPeerMethod = this.helperMembers != null && !this.anonymousDelegatesThatCaptureLocalsOrParameters.ContainsKey(anonymousDelegate);
      bool isStaticMethod = isPeerMethod && !this.anonymousDelegatesThatCaptureThis.ContainsKey(anonymousDelegate);
      var body = new SourceMethodBody(this.host, this.sourceLocationProvider) {
        Block = anonymousDelegate.Body,
        LocalsAreZeroed = true
      };
      var counter = isPeerMethod ? this.helperMembers.Count : this.anonymousDelegateCounter++;
      var prefix = "<"+this.method.Name.Value;
      prefix += isPeerMethod ? ">p__" : ">b__";
      var method = new MethodDefinition() {
        ContainingTypeDefinition = isPeerMethod ? this.method.ContainingTypeDefinition : this.currentClosureClass,
        Name = this.host.NameTable.GetNameFor(prefix+counter),
        Visibility = isPeerMethod ? TypeMemberVisibility.Private : TypeMemberVisibility.Public,
        Body = body,
        CallingConvention = isStaticMethod ? CallingConvention.Default : CallingConvention.HasThis,
        InternFactory = this.host.InternFactory,
        Parameters = anonymousDelegate.Parameters,
        Type = anonymousDelegate.ReturnType,
        IsCil = true,
        IsStatic = isStaticMethod,
        IsHiddenBySignature = true,
      };
      body.MethodDefinition = method;
      if (method.Parameters != null) {
        foreach (ParameterDefinition parameterDefinition in method.Parameters)
          parameterDefinition.ContainingSignature = method;
      }

      if (isPeerMethod) {
        this.helperMembers.Add(method);
        if (this.method.IsGeneric) this.MakeDelegateMethodGeneric(method);
        method.Attributes = new List<ICustomAttribute>(1);
        method.Attributes.Add(this.compilerGenerated);
      } else {
        this.currentClosureClass.Methods.Add(method);
        this.isInsideAnonymousMethod = true;
        this.RewriteChildren(method);
        this.isInsideAnonymousMethod = false;
      }

      IMethodReference methodReference = method;
      ITypeReference containingTypeDefinitionInstance = method.ContainingTypeDefinition;
      if (isPeerMethod)
        containingTypeDefinitionInstance = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)method.ContainingTypeDefinition, this.host.InternFactory);
      if ((isPeerMethod && method.ContainingTypeDefinition != containingTypeDefinitionInstance) || 
          (!isPeerMethod && this.currentClosureClass != this.currentClosureInstance)) {
        methodReference = new MethodReference() {
          CallingConvention = method.CallingConvention,
          ContainingType = isPeerMethod ? containingTypeDefinitionInstance : this.currentClosureInstance,
          GenericParameterCount = method.GenericParameterCount,
          InternFactory = this.host.InternFactory,
          Name = method.Name,
          Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters),
          Type = method.Type,
        };
      }

      if (!method.IsGeneric) return methodReference;
      return new GenericMethodInstanceReference() {
        CallingConvention = method.CallingConvention,
        ContainingType = method.ContainingTypeDefinition,
        GenericArguments = new List<ITypeReference>(IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(method.GenericParameters)),
        GenericMethod = methodReference,
        InternFactory = this.host.InternFactory,
        Name = method.Name,
        Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters),
        Type = method.Type,
      };
    }
コード例 #3
0
        public override void BuildMethod()
        {
            AddStatement.DeclareInterceptedType(field.ContainingType.ResolvedType);

            Context.Log.WriteTrace("  Adding: var interceptedField = interceptedType.GetField('{0}');", field.Name.Value);
            Context.Block.Statements.Add(
                Declare.Variable<FieldInfo>("interceptedField").As(
                    Call.VirtualMethod("GetField", typeof (string)).ThatReturns<FieldInfo>().WithArguments(
                        Constant.Of(field.Name.Value)).On("interceptedType"))
            );

            AddStatement.DeclareArgumentsList();
            AddStatement.AddArgumentToList(Params["assignedValue"]);

            var actionT = SharpMockTypes.Actions[1];
            var actionActualT = new GenericTypeInstanceReference();
            actionActualT.GenericType = actionT;
            actionActualT.GenericArguments.Add(field.Type);

            var assignment = new AnonymousDelegate();
            assignment.Type = actionActualT;
            assignment.ReturnType = Context.Host.PlatformType.SystemVoid;
            assignment.CallingConvention = CallingConvention.HasThis;

            var parameterDefinition = new ParameterDefinition();
            parameterDefinition.Index = 0;
            parameterDefinition.Type = field.Type;
            parameterDefinition.Name = Context.Host.NameTable.GetNameFor("alteredValue");
            parameterDefinition.ContainingSignature = assignment;

            assignment.Parameters.Add(parameterDefinition);

            var assignmentBody = new BlockStatement();
            var assignActualField = new ExpressionStatement();
            var actualField = new TargetExpression();
            actualField.Type = field.Type;
            actualField.Definition = field;
            var value = new BoundExpression();
            value.Type = field.Type;
            value.Definition = parameterDefinition;
            var assignValueToField = new Assignment();
            assignValueToField.Source = value;
            assignValueToField.Target = actualField;
            assignValueToField.Type = field.Type;
            assignActualField.Expression = assignValueToField;

            actualField.Type = field.Type;
            actualField.Definition = field;

            assignmentBody.Statements.Add(assignActualField);
            assignmentBody.Statements.Add(new ReturnStatement());
            assignment.Body = assignmentBody;

            Context.Block.Statements.Add(
                Declare.Variable("local_0", actionActualT).As(assignment)
            );

            AddStatement.DeclareRegistryInterceptor();
            AddStatement.DeclareInvocation();
            AddStatement.SetArgumentsOnInvocation();
            AddStatement.SetOriginalCallOnInvocation();
            AddStatement.SetTargetOnInvocationToNull();

            Context.Block.Statements.Add(
                Do(Call.PropertySetter<MemberInfo>("OriginalCallInfo").WithArguments("interceptedField").On("invocation"))
            );

            AddStatement.CallShouldInterceptOnInterceptor();
            AddStatement.CallInterceptOnInterceptor();

            Context.Block.Statements.Add(Return.Void());
        }
コード例 #4
0
ファイル: Copier.cs プロジェクト: riverar/devtools
 /// <summary>
 /// Visits the specified anonymous delegate.
 /// </summary>
 /// <param name="anonymousDelegate">The anonymous delegate.</param>
 /// <returns></returns>
 protected virtual IExpression DeepCopy(AnonymousDelegate anonymousDelegate)
 {
     //^ requires this.cache.ContainsKey(anonymousDelegate);
       var pars = new List<IParameterDefinition>();
       foreach (var p in anonymousDelegate.Parameters) {
     var newp = this.DeepCopy(this.GetMutableCopyParamAnonymDeleg(p));
     pars.Add(newp);
       }
       anonymousDelegate.Parameters = pars;
       anonymousDelegate.Body = (IBlockStatement)this.Substitute(anonymousDelegate.Body);
       anonymousDelegate.ReturnType = this.Substitute(anonymousDelegate.ReturnType);
       anonymousDelegate.Type = this.Substitute(anonymousDelegate.Type);
       return anonymousDelegate;
 }
コード例 #5
0
ファイル: Copier.cs プロジェクト: riverar/devtools
 /// <summary>
 /// Visits the specified anonymous method.
 /// </summary>
 /// <param name="anonymousMethod">The anonymous method.</param>
 public override void Visit(IAnonymousDelegate anonymousMethod)
 {
     AnonymousDelegate mutableAnonymousDelegate = new AnonymousDelegate(anonymousMethod);
     this.resultExpression = this.myCodeCopier.DeepCopy(mutableAnonymousDelegate);
 }
コード例 #6
0
        private IExpression ConvertToAnonymousDelegate(CreateDelegateInstance createDelegateInstance, bool iteratorsHaveNotBeenDecompiled)
        {
            IMethodDefinition closureMethod = createDelegateInstance.MethodToCallViaDelegate.ResolvedMethod;
              if (this.sourceMethodBody.privateHelperMethodsToRemove == null) this.sourceMethodBody.privateHelperMethodsToRemove = new Dictionary<uint, IMethodDefinition>();
              IMethodBody closureMethodBody = UnspecializedMethods.GetMethodBodyFromUnspecializedVersion(closureMethod);
              AnonymousDelegate anonDel = new AnonymousDelegate();
              anonDel.CallingConvention = closureMethod.CallingConvention;
              var unspecializedClosureMethod = UnspecializedMethods.UnspecializedMethodDefinition(closureMethod);
              this.sourceMethodBody.privateHelperMethodsToRemove[unspecializedClosureMethod.InternedKey] = unspecializedClosureMethod;
              anonDel.Parameters = new List<IParameterDefinition>(unspecializedClosureMethod.Parameters);
              for (int i = 0, n = anonDel.Parameters.Count; i < n; i++) {
            IParameterDefinition closureMethodPar = UnspecializedParameterDefinition(anonDel.Parameters[i]);
            ParameterDefinition par = new ParameterDefinition();
            this.parameterMap.Add(closureMethodPar, par);
            par.Copy(closureMethodPar, this.host.InternFactory);
            par.ContainingSignature = anonDel;
            anonDel.Parameters[i] = par;
              }
              var alreadyDecompiledBody = closureMethodBody as SourceMethodBody;
              ISourceMethodBody anonDelSourceMethodBody = alreadyDecompiledBody;
              if (alreadyDecompiledBody == null) {
            var alreadyDecompiledBody2 = closureMethodBody as Microsoft.Cci.MutableCodeModel.SourceMethodBody;
            if (alreadyDecompiledBody2 == null) {
              var smb = new SourceMethodBody(closureMethodBody, this.sourceMethodBody.host,
            this.sourceMethodBody.sourceLocationProvider, this.sourceMethodBody.localScopeProvider, this.sourceMethodBody.options);
              anonDelSourceMethodBody = smb;
              anonDel.Body = smb.Block;
            } else {
              anonDel.Body = alreadyDecompiledBody2.Block;
              anonDelSourceMethodBody = alreadyDecompiledBody2;
            }
              } else {
            anonDel.Body = alreadyDecompiledBody.Block;
              }

              anonDel.ReturnValueIsByRef = closureMethod.ReturnValueIsByRef;
              if (closureMethod.ReturnValueIsModified)
            anonDel.ReturnValueCustomModifiers = new List<ICustomModifier>(closureMethod.ReturnValueCustomModifiers);
              anonDel.ReturnType = closureMethod.Type;
              anonDel.Type = createDelegateInstance.Type;

              if (iteratorsHaveNotBeenDecompiled && unspecializedClosureMethod.ContainingTypeDefinition.IsGeneric &&
            unspecializedClosureMethod.ContainingTypeDefinition.GenericParameterCount ==
            this.sourceMethodBody.MethodDefinition.ContainingTypeDefinition.GenericParameterCount) {
            var mapper = new GenericTypeParameterMapper(this.host, this.sourceMethodBody.MethodDefinition.ContainingTypeDefinition,
              unspecializedClosureMethod.ContainingTypeDefinition);
            mapper.Rewrite(anonDel);
              }

              BlockStatement bs = anonDel.Body as BlockStatement;
              if (bs != null) {
            var savedReferencedLabels = this.referencedLabels;
            this.referencedLabels = null;
            anonDel.Body = this.RemoveCompilationArtifacts(bs);
            this.referencedLabels = savedReferencedLabels;
              }
              IExpression result = anonDel;

              if (this.sourceMethodBody.MethodDefinition.IsGeneric) {
            if (unspecializedClosureMethod.IsGeneric)
              this.genericParameterMapper = new GenericMethodParameterMapper(this.host, this.sourceMethodBody.MethodDefinition, unspecializedClosureMethod);
            // If the closure method was not generic, then its containing type is generic
            // and the generic parameter mapper was created when the closure instance creation
            // was discovered at the beginning of this visitor.
            if (this.genericParameterMapper != null) {
              result = this.genericParameterMapper.Visit(result);
              foreach (var v in this.capturedBinding.Values) {
            // Do NOT visit any of the parameters in the table because that
            // will cause them to (possibly) have their types changed. But
            // they already have the correct type because they are parameters
            // of the enclosing method.
            // But the locals are ones that were created by this visitor so
            // they need their types updated.
            LocalDefinition ld = v.Definition as LocalDefinition;
            if (ld != null) {
              ld.Type = this.genericParameterMapper.Visit(ld.Type);
              ld.MethodDefinition = this.sourceMethodBody.MethodDefinition;
            }
              }
            }
              }

              return result;
        }
コード例 #7
0
 public override IExpression Visit(AnonymousDelegate anonymousDelegate)
 {
     return anonymousDelegate;
 }
コード例 #8
0
ファイル: Mutator.cs プロジェクト: riverar/devtools
 /// <summary>
 /// Rewrites the children of the given anonymous delegate expression.
 /// </summary>
 /// <param name="anonymousDelegate"></param>
 public virtual void RewriteChildren(AnonymousDelegate anonymousDelegate)
 {
     this.RewriteChildren((Expression)anonymousDelegate);
       anonymousDelegate.Parameters = this.Rewrite(anonymousDelegate.Parameters);
       anonymousDelegate.Body = this.Rewrite((BlockStatement)anonymousDelegate.Body);
       anonymousDelegate.ReturnType = this.Rewrite(anonymousDelegate.ReturnType);
       if (anonymousDelegate.ReturnValueIsModified)
     anonymousDelegate.ReturnValueCustomModifiers =this.Rewrite(anonymousDelegate.ReturnValueCustomModifiers);
 }
コード例 #9
0
ファイル: Mutator.cs プロジェクト: riverar/devtools
 /// <summary>
 /// Visits the specified anonymous method.
 /// </summary>
 /// <param name="anonymousMethod">The anonymous method.</param>
 public override void Visit(IAnonymousDelegate anonymousMethod)
 {
     AnonymousDelegate mutableAnonymousDelegate = anonymousMethod as AnonymousDelegate;
     if (alwaysMakeACopy || mutableAnonymousDelegate == null) mutableAnonymousDelegate = new AnonymousDelegate(anonymousMethod);
     this.resultExpression = this.myCodeMutator.Visit(mutableAnonymousDelegate);
 }
コード例 #10
0
ファイル: Mutator.cs プロジェクト: riverar/devtools
 /// <summary>
 /// Visits the specified anonymous delegate.
 /// </summary>
 /// <param name="anonymousDelegate">The anonymous delegate.</param>
 /// <returns></returns>
 public virtual IExpression Visit(AnonymousDelegate anonymousDelegate)
 {
     this.path.Push(anonymousDelegate);
       anonymousDelegate.Parameters = this.Visit(anonymousDelegate.Parameters);
       anonymousDelegate.Body = this.Visit(anonymousDelegate.Body);
       anonymousDelegate.ReturnType = this.Visit(anonymousDelegate.ReturnType);
       anonymousDelegate.Type = this.Visit(anonymousDelegate.Type);
       this.path.Pop();
       return anonymousDelegate;
 }
コード例 #11
0
ファイル: Mutator.cs プロジェクト: riverar/devtools
 /// <summary>
 /// Visits the specified anonymous delegate.
 /// </summary>
 /// <param name="anonymousDelegate">The anonymous delegate.</param>
 /// <returns></returns>
 public virtual IExpression Visit(AnonymousDelegate anonymousDelegate)
 {
     this.path.Push(anonymousDelegate);
       for (int i = 0, n = anonymousDelegate.Parameters.Count; i < n; i++)
     anonymousDelegate.Parameters[i] = this.Visit(anonymousDelegate.Parameters[i]);
       anonymousDelegate.Body = this.Visit(anonymousDelegate.Body);
       anonymousDelegate.ReturnType = this.Visit(anonymousDelegate.ReturnType);
       anonymousDelegate.Type = this.Visit(anonymousDelegate.Type);
       this.path.Pop();
       return anonymousDelegate;
 }