RemoveAnonymousDelegates() public method

When given a method definition and a block of statements that represents the Block property of the body of the method this method returns a semantically equivalent SourceMethod with a body that no longer has any anonymous delegate expressions. The given block of statements is mutated in place. Any types that get defined in order to implement the body semantics are returned (null if no such types are defined).
public RemoveAnonymousDelegates ( IMethodDefinition method, BlockStatement body ) : ICollection
method IMethodDefinition The method containing the block that is to be rewritten.
body BlockStatement The block to be rewritten. /// The entire tree rooted at the block must be mutable and the nodes must not be shared with anything else.
return ICollection
Ejemplo n.º 1
0
        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;
    }