Esempio n. 1
0
        /// <summary>
        /// Rewrite the given node to eliminate lambda expressions.  Also returned are the method symbols and their
        /// bound bodies for the extracted lambda bodies. These would typically be emitted by the caller such as
        /// MethodBodyCompiler.  See this class' documentation
        /// for a more thorough explanation of the algorithm and its use by clients.
        /// </summary>
        /// <param name="node">The bound node to be rewritten</param>
        /// <param name="thisType">The type of the top-most frame</param>
        /// <param name="thisParameter">The "this" parameter in the top-most frame, or null if static method</param>
        /// <param name="method">The containing method of the node to be rewritten</param>
        /// <param name="compilationState">The caller's buffer into which we produce additional methods to be emitted by the caller</param>
        /// <param name="diagnostics">Diagnostic bag for diagnostics</param>
        /// <param name="analysis">A caller-provided analysis of the node's lambdas</param>
        /// <param name="generateDebugInfo"></param>
        /// <param name="assignLocals">The rewritten tree should include assignments of the original locals to the lifted proxies</param>
        public static BoundStatement Rewrite(
            BoundStatement node,
            NamedTypeSymbol thisType,
            ParameterSymbol thisParameter,
            MethodSymbol method,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            Analysis analysis,
            bool generateDebugInfo,
            bool assignLocals = false)
        {
            Debug.Assert((object)thisType != null);
            Debug.Assert(((object)thisParameter == null) || (thisParameter.Type == thisType));

            CheckLocalsDefined(node);
            var rewriter = new LambdaRewriter(
                analysis,
                thisType,
                thisParameter,
                method,
                compilationState,
                diagnostics,
                generateDebugInfo,
                assignLocals);

            analysis.ComputeLambdaScopesAndFrameCaptures();
            rewriter.MakeFrames();
            var body = rewriter.AddStatementsIfNeeded((BoundStatement)rewriter.Visit(node));

            CheckLocalsDefined(body);
            return(body);
        }
Esempio n. 2
0
 public LocalFunctionReferenceRewriter(LambdaRewriter lambdaRewriter)
 {
     _lambdaRewriter = lambdaRewriter;
 }
Esempio n. 3
0
        internal static BoundStatement LowerStatement(
            bool generateDebugInfo,
            MethodSymbol method,
            BoundStatement body,
            SynthesizedSubmissionFields previousSubmissionFields,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
        {
            if (body.HasErrors)
            {
                return(body);
            }

            bool sawLambdas;
            bool sawDynamicOperations;
            bool sawAwaitInExceptionHandler;
            var  loweredBody = LocalRewriter.Rewrite(
                method.DeclaringCompilation,
                generateDebugInfo,
                method,
                method.ContainingType,
                body,
                compilationState,
                diagnostics,
                previousSubmissionFields,
                out sawLambdas,
                out sawDynamicOperations,
                out sawAwaitInExceptionHandler);

            if (sawDynamicOperations && compilationState.ModuleBuilder.IsENCDelta)
            {
                // Dynamic operations are not supported in ENC.
                var location = method.Locations[0];
                diagnostics.Add(new CSDiagnosticInfo(ErrorCode.ERR_EnCNoDynamicOperation), location);
            }

            if (loweredBody.HasErrors)
            {
                return(loweredBody);
            }

            if (sawAwaitInExceptionHandler)
            {
                // If we have awaits in handlers, we need to
                // replace handlers with synthetic ones which can be consumed by async rewriter.
                // The reason why this rewrite happens before the lambda rewrite
                // is that we may need access to exception locals and it would be fairly hard to do
                // if these locals are captured into closures (possibly nested ones).
                Debug.Assert(method.IteratorElementType == null);
                loweredBody = AsyncHandlerRewriter.Rewrite(
                    generateDebugInfo,
                    method,
                    method.ContainingType,
                    loweredBody,
                    compilationState,
                    diagnostics);
            }

            if (loweredBody.HasErrors)
            {
                return(loweredBody);
            }

            BoundStatement bodyWithoutLambdas = loweredBody;

            if (sawLambdas)
            {
                LambdaRewriter.Analysis lambdaAnalysis = LambdaRewriter.Analysis.Analyze(loweredBody, method, out sawLambdas);
                if (sawLambdas)
                {
                    bodyWithoutLambdas = LambdaRewriter.Rewrite(loweredBody, method.ContainingType, method.ThisParameter, method, compilationState, diagnostics, lambdaAnalysis, generateDebugInfo);
                }
            }

            if (bodyWithoutLambdas.HasErrors)
            {
                return(bodyWithoutLambdas);
            }

            BoundStatement bodyWithoutIterators = IteratorRewriter.Rewrite(bodyWithoutLambdas, method, compilationState, diagnostics, generateDebugInfo);

            if (bodyWithoutIterators.HasErrors)
            {
                return(bodyWithoutIterators);
            }

            BoundStatement bodyWithoutAsync = AsyncRewriter2.Rewrite(bodyWithoutIterators, method, compilationState, diagnostics, generateDebugInfo);

            return(bodyWithoutAsync);
        }
 public LocalFunctionReferenceRewriter(LambdaRewriter lambdaRewriter)
 {
     _lambdaRewriter = lambdaRewriter;
 }