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); }
/// <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; }