public ICollection <ITypeDefinition> /*?*/ TranslateMethod(IMethodDefinition method) { // Let an exception be thrown if this is not as expected. var methodBody = (ISourceMethodBody)method.Body; var block = (BlockStatement)methodBody.Block; 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); }
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); }
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; ISynchronizationInformation /*?*/ synchronizationInformation; uint size; 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) { IMethodDefinition /*?*/ asyncMethod = null; if (this.localScopeProvider != null) { var asyncInfo = this.localScopeProvider.GetSynchronizationInformation(this); if (asyncInfo != null) { asyncMethod = asyncInfo.AsyncMethod; } } var converter = new CodeModelToILConverter(this.host, this.MethodDefinition, this.sourceLocationProvider, asyncMethod, this.iteratorLocalCount); converter.TrackExpressionSourceLocations = this.trackExpressionSourceLocations; converter.ConvertToIL(this.Block); iteratorScopes = converter.GetIteratorScopes(); localScopes = converter.GetLocalScopes(); localVariables = converter.GetLocalVariables(); maxStack = converter.MaximumStackSizeNeeded; size = converter.GetBodySize(); namespaceScopes = converter.GetNamespaceScopes(); operations = converter.GetOperations(); operationExceptionInformation = converter.GetOperationExceptionInformation(); synchronizationInformation = converter.GetSynchronizationInformation(); } 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, this.sourceLocationProvider).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; size = normalizedBody.Size; namespaceScopes = normalizedBody.NamespaceScopes; operations = normalizedBody.Operations; operationExceptionInformation = normalizedBody.OperationExceptionInformation; synchronizationInformation = normalizedBody.SynchronizationInformation; 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.synchronizationInformation = synchronizationInformation; this.privateHelperTypes = privateHelperTypes; this.size = size; } }