示例#1
0
        internal ImmutableArray <Diagnostic> FlowDiagnostics(CSharpCompilation compilation)
        {
            var flowDiagnostics = DiagnosticBag.GetInstance();

            foreach (var method in AllMethods(compilation.SourceModule.GlobalNamespace))
            {
                var sourceSymbol = method as SourceMemberMethodSymbol;
                if (sourceSymbol == null)
                {
                    continue;
                }

                var boundBody = MethodCompiler.BindMethodBody(
                    sourceSymbol,
                    new TypeCompilationState(sourceSymbol.ContainingType, compilation, null),
                    new BindingDiagnosticBag(new DiagnosticBag())
                    );
                if (boundBody != null)
                {
                    FlowAnalysisPass.Rewrite(
                        sourceSymbol,
                        boundBody,
                        flowDiagnostics,
                        hasTrailingExpression: false,
                        originalBodyNested: false
                        );
                }
            }

            return(flowDiagnostics.ToReadOnlyAndFree <Diagnostic>());
        }
示例#2
0
        internal static BoundStatement AnalyzeMethodBody(MethodBodyCompiler methodCompiler, MethodSymbol method, BoundBlock body, DiagnosticBag diagnostics)
        {
            Debug.Assert(diagnostics != null);

            body = FlowAnalysisPass.Rewrite(method, body, diagnostics);
            var analyzedBody = (BoundBlock)RewritePass.Rewrite(methodCompiler, method.ContainingType, body);

            return(RewritePass.InsertPrologueSequencePoint(analyzedBody, method));
        }
示例#3
0
        internal BoundStatement AnalyzeMethodBody(MethodSymbol method, BoundBlock block, bool generateDebugInfo, DiagnosticBag diagnostics)
        {
            var diagnostics2 = DiagnosticBag.GetInstance();
            var analyzed1    = FlowAnalysisPass.Rewrite(method, block, diagnostics2);

            if (diagnostics != null)
            {
                diagnostics.Add(diagnostics2);
            }
            diagnostics2.Free();
            return(RewritePass.Rewrite(analyzed1, generateDebugInfo));
        }
示例#4
0
        internal ImmutableArray <Diagnostic> FlowDiagnostics(CSharpCompilation compilation)
        {
            var flowDiagnostics = DiagnosticBag.GetInstance();

            foreach (var method in AllMethods(compilation.SourceModule.GlobalNamespace))
            {
                var sourceSymbol = method as SourceMethodSymbol;
                if (sourceSymbol == null)
                {
                    continue;
                }

                var boundBody = Compiler.BindMethodBody(sourceSymbol, new DiagnosticBag());
                if (boundBody != null)
                {
                    FlowAnalysisPass.Rewrite(sourceSymbol, boundBody, flowDiagnostics);
                }
            }

            return(flowDiagnostics.ToReadOnlyAndFree <Diagnostic>());
        }
示例#5
0
        private BoundLambda ReallyBind(NamedTypeSymbol delegateType)
        {
            var     invokeMethod = DelegateInvokeMethod(delegateType);
            RefKind refKind;
            var     returnType = DelegateReturnType(invokeMethod, out refKind);

            LambdaSymbol lambdaSymbol;
            Binder       lambdaBodyBinder;
            BoundBlock   block;

            var diagnostics = DiagnosticBag.GetInstance();

            // when binding for real (not for return inference), there is still
            // a good chance that we could reuse a body of a lambda previously bound for
            // return type inference.
            var cacheKey = ReturnInferenceCacheKey.Create(delegateType, IsAsync);

            BoundLambda returnInferenceLambda;

            if (_returnInferenceCache.TryGetValue(cacheKey, out returnInferenceLambda) && returnInferenceLambda.InferredFromSingleType)
            {
                lambdaSymbol = returnInferenceLambda.Symbol;
                if ((object)LambdaSymbol.InferenceFailureReturnType != lambdaSymbol.ReturnType &&
                    lambdaSymbol.ReturnType == returnType && lambdaSymbol.RefKind == refKind)
                {
                    lambdaBodyBinder = returnInferenceLambda.Binder;
                    block            = returnInferenceLambda.Body;
                    diagnostics.AddRange(returnInferenceLambda.Diagnostics);

                    goto haveLambdaBodyAndBinders;
                }
            }

            lambdaSymbol = new LambdaSymbol(
                binder.Compilation,
                binder.ContainingMemberOrLambda,
                _unboundLambda,
                cacheKey.ParameterTypes,
                cacheKey.ParameterRefKinds,
                refKind,
                returnType,
                diagnostics);
            lambdaBodyBinder = new ExecutableCodeBinder(_unboundLambda.Syntax, lambdaSymbol, ParameterBinder(lambdaSymbol, binder));

            if (lambdaSymbol.RefKind == CodeAnalysis.RefKind.RefReadOnly)
            {
                binder.Compilation.EnsureIsReadOnlyAttributeExists(diagnostics, lambdaSymbol.DiagnosticLocation, modifyCompilationForRefReadOnly: false);
            }

            ParameterHelpers.EnsureIsReadOnlyAttributeExists(lambdaSymbol.Parameters, diagnostics, modifyCompilationForRefReadOnly: false);

            block = BindLambdaBody(lambdaSymbol, lambdaBodyBinder, diagnostics);

            ((ExecutableCodeBinder)lambdaBodyBinder).ValidateIteratorMethods(diagnostics);
            ValidateUnsafeParameters(diagnostics, cacheKey.ParameterTypes);

haveLambdaBodyAndBinders:

            bool reachableEndpoint = ControlFlowPass.Analyze(binder.Compilation, lambdaSymbol, block, diagnostics);

            if (reachableEndpoint)
            {
                if (DelegateNeedsReturn(invokeMethod))
                {
                    // Not all code paths return a value in {0} of type '{1}'
                    diagnostics.Add(ErrorCode.ERR_AnonymousReturnExpected, lambdaSymbol.DiagnosticLocation, this.MessageID.Localize(), delegateType);
                }
                else
                {
                    block = FlowAnalysisPass.AppendImplicitReturn(block, lambdaSymbol);
                }
            }

            if (IsAsync && !ErrorFacts.PreventsSuccessfulDelegateConversion(diagnostics))
            {
                if ((object)returnType != null && // Can be null if "delegateType" is not actually a delegate type.
                    returnType.SpecialType != SpecialType.System_Void &&
                    !returnType.IsNonGenericTaskType(binder.Compilation) &&
                    !returnType.IsGenericTaskType(binder.Compilation))
                {
                    // Cannot convert async {0} to delegate type '{1}'. An async {0} may return void, Task or Task&lt;T&gt;, none of which are convertible to '{1}'.
                    diagnostics.Add(ErrorCode.ERR_CantConvAsyncAnonFuncReturns, lambdaSymbol.DiagnosticLocation, lambdaSymbol.MessageID.Localize(), delegateType);
                }
            }

            if (IsAsync)
            {
                Debug.Assert(lambdaSymbol.IsAsync);
                SourceOrdinaryMethodSymbol.ReportAsyncParameterErrors(lambdaSymbol.Parameters, diagnostics, lambdaSymbol.DiagnosticLocation);
            }

            var result = new BoundLambda(_unboundLambda.Syntax, block, diagnostics.ToReadOnlyAndFree(), lambdaBodyBinder, delegateType, inferReturnType: false)
            {
                WasCompilerGenerated = _unboundLambda.WasCompilerGenerated
            };

            return(result);
        }