コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
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;
            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;
            }
        }