Microsoft.Cci.MutableCodeModel.SourceMethodBody.GenerateIL C# (CSharp) Method

GenerateIL() private method

private GenerateIL ( ) : void
return void
    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;
      }
    }