A class providing functionality to rewrite high level constructs such as anonymous delegates and yield statements into helper classes and methods, thus making it easier to generate IL from the CodeModel.
Пример #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;
              }
        }