Microsoft.Cci.MutableCodeModel.MethodBodyNormalizer.GetNormalizedSourceMethodBodyFor C# (CSharp) Method

GetNormalizedSourceMethodBodyFor() public method

Given a method definition and a block of statements that represents the Block property of the body of the method, returns a SourceMethod with a body that no longer has any yield statements or anonymous delegate expressions. The given block of statements is mutated in place.
public GetNormalizedSourceMethodBodyFor ( IMethodDefinition method, IBlockStatement body ) : SourceMethodBody
method IMethodDefinition
body IBlockStatement
return SourceMethodBody
    public SourceMethodBody GetNormalizedSourceMethodBodyFor(IMethodDefinition method, IBlockStatement body) {
      var finder = new ClosureFinder(method, this.host);
      finder.Traverse(body);

      var privateHelperTypes = new List<ITypeDefinition>();
      if (finder.foundYield) {
        this.isIteratorBody = true;
        body = this.GetNormalizedIteratorBody(body, method, privateHelperTypes);
      }
      SourceMethodBody result = new SourceMethodBody(this.host, this.sourceLocationProvider);
      result.Block = body;
      result.MethodDefinition = method;
      result.IsNormalized = true;
      result.LocalsAreZeroed = true;
      result.PrivateHelperTypes = privateHelperTypes;

      return result;
    }

Usage Example

示例#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;
              }
        }