public override IParameterDefinition Rewrite(IParameterDefinition parameterDefinition)
        {
            //we need to copy the parameters because they still come from the closure method.
            var copy = new ParameterDefinition();

            copy.Copy(parameterDefinition, this.host.InternFactory);
            copy.ContainingSignature = this.anonymousDelegate;
            this.parameterMap.Add((uint)parameterDefinition.Name.UniqueKey, copy);
            return(copy);
        }
Exemple #2
0
 /// <summary>
 /// Get mutable copy of a parameter definition of an anonymous delegate. The parameters of anonymous delegate
 /// are not visited until the code of a souce method body is visited.
 /// </summary>
 /// <param name="parameterDefinition"></param>
 /// <returns></returns>
 private ParameterDefinition GetMutableCopyParamAnonymDeleg(IParameterDefinition parameterDefinition)
 {
     ParameterDefinition/*?*/ result;
       object/*?*/ cachedValue = null;
       this.cache.TryGetValue(parameterDefinition, out cachedValue);
       result = cachedValue as ParameterDefinition;
       if (result != null) return result;
       result = new ParameterDefinition();
       this.cache.Add(parameterDefinition, result);
       this.cache.Add(result, result);
       result.Copy(parameterDefinition, this.host.InternFactory);
       return result;
 }
        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;
        }