private void GenerateIL() { IEnumerable<ILocalDefinition> localVariables; ushort maxStack; IEnumerable<ILocalScope> iteratorScopes; IEnumerable<ILocalScope> localScopes; IEnumerable<INamespaceScope> namespaceScopes; IEnumerable<IOperation> operations; IEnumerable<IOperationExceptionInformation> operationExceptionInformation; List<ITypeDefinition>/*?*/ privateHelperTypes = this.privateHelperTypes; var isNormalized = this.isNormalized; NormalizationChecker checker = null; if (!isNormalized) { //Assuming that most methods are not iterators and do not contain anonymous delegates, it is worth our while to check if this is really the case. checker = new NormalizationChecker(); checker.TraverseChildren(this.Block); isNormalized = !checker.foundAnonymousDelegate && !checker.foundYield; } if (isNormalized) { var converter = new CodeModelToILConverter(this.host, this.MethodDefinition, this.sourceLocationProvider, this.iteratorLocalCount); converter.ConvertToIL(this.Block); iteratorScopes = converter.GetIteratorScopes(); localScopes = converter.GetLocalScopes(); localVariables = converter.GetLocalVariables(); maxStack = converter.MaximumStackSizeNeeded; namespaceScopes = converter.GetNamespaceScopes(); operations = converter.GetOperations(); operationExceptionInformation = converter.GetOperationExceptionInformation(); } else { //This object might already be immutable and we are just doing delayed initialization, so make a copy of this.Block. var mutableBlock = new CodeDeepCopier(this.host).Copy(this.Block); if (checker.foundAnonymousDelegate) { var remover = new AnonymousDelegateRemover(this.host, this.sourceLocationProvider); remover.RemoveAnonymousDelegates(this.MethodDefinition, mutableBlock); privateHelperTypes = remover.closureClasses; } var normalizer = new MethodBodyNormalizer(this.host, this.sourceLocationProvider); var normalizedBody = (SourceMethodBody)normalizer.GetNormalizedSourceMethodBodyFor(this.MethodDefinition, mutableBlock); normalizedBody.isNormalized = true; iteratorScopes = normalizedBody.IteratorScopes; localScopes = normalizedBody.LocalScopes; localVariables = normalizedBody.LocalVariables; maxStack = normalizedBody.MaxStack; namespaceScopes = normalizedBody.NamespaceScopes; operations = normalizedBody.Operations; operationExceptionInformation = normalizedBody.OperationExceptionInformation; if (privateHelperTypes == null) privateHelperTypes = normalizedBody.PrivateHelperTypes; else //this can happen when this source method body has already been partially normalized, for instance by the removal of yield statements. privateHelperTypes.AddRange(normalizedBody.PrivateHelperTypes); } lock (this) { if (this.ilWasGenerated) return; this.ilWasGenerated = true; this.iteratorScopes = iteratorScopes; this.localScopes = localScopes; this.localVariables = localVariables; this.maxStack = maxStack; this.namespaceScopes = namespaceScopes; this.operations = operations; this.operationExceptionInformation = operationExceptionInformation; this.privateHelperTypes = privateHelperTypes; } }
public ICollection<ITypeDefinition>/*?*/ TranslateMethod(IMethodDefinition method) { var methodBody = method.Body as ISourceMethodBody; if (methodBody == null) return null; var block = methodBody.Block as BlockStatement; // TODO: Error if cast fails? ICollection<ITypeDefinition> newTypes = null; if (block != null) { var remover = new AnonymousDelegateRemover(this.sink.host, this.PdbReader); newTypes = remover.RemoveAnonymousDelegates(methodBody.MethodDefinition, block); } StmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List<object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null))); this.Traverse(methodBody); return newTypes; }