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>()); }
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)); }
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)); }
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>()); }
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<T>, 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); }