예제 #1
0
        /// <summary>
        /// If the member is generic, construct it with the CrefTypeParameterSymbols that should be in scope.
        /// </summary>
        private Symbol ConstructWithCrefTypeParameters(int arity, TypeArgumentListSyntax typeArgumentListSyntax, Symbol symbol)
        {
            if (arity > 0)
            {
                SeparatedSyntaxList <TypeSyntax> typeArgumentSyntaxes = typeArgumentListSyntax.Arguments;
                TypeSymbol[] typeArgumentSymbols = new TypeSymbol[arity];

                DiagnosticBag unusedDiagnostics = DiagnosticBag.GetInstance();
                for (int i = 0; i < arity; i++)
                {
                    TypeSyntax typeArgumentSyntax = typeArgumentSyntaxes[i];

                    typeArgumentSymbols[i] = BindType(typeArgumentSyntax, unusedDiagnostics);

                    // Should be in a WithCrefTypeParametersBinder.
                    Debug.Assert(typeArgumentSyntax.ContainsDiagnostics || !typeArgumentSyntax.SyntaxTree.ReportDocumentationCommentDiagnostics() ||
                                 (!unusedDiagnostics.HasAnyErrors() && typeArgumentSymbols[i] is CrefTypeParameterSymbol));

                    unusedDiagnostics.Clear();
                }
                unusedDiagnostics.Free();

                if (symbol.Kind == SymbolKind.Method)
                {
                    symbol = ((MethodSymbol)symbol).Construct(typeArgumentSymbols);
                }
                else
                {
                    Debug.Assert(symbol is NamedTypeSymbol);
                    symbol = ((NamedTypeSymbol)symbol).Construct(typeArgumentSymbols);
                }
            }

            return(symbol);
        }
예제 #2
0
        private static DiagnosticBag DiagnoseCompilation(Compilation compilation, DiagnosticFormatter diagnosticFormatter)
        {
            var diagnostics = new DiagnosticBag();

            diagnostics.AddRange(compilation.GetParseDiagnostics());
            ThrowIfAnyCompilationErrors(diagnostics, diagnosticFormatter);
            diagnostics.Clear();
            return(diagnostics);
        }
예제 #3
0
        internal static BoundBlock FixCodeBlockProblems(LambdaSymbol lambdaSymbol, Binder lambdaBodyBinder, BoundBlock block, DiagnosticBag diagnostics)
        {
            // check for a Lambda that returns a USUAL
            var usualType = lambdaBodyBinder.Compilation.UsualType();

            if (lambdaSymbol.ReturnType != usualType)
            {
                return(block);
            }
            // handle 2 problems:
            // 1) no statements, then add a return statement
            // 2) last statement is a void expression. Then the conversion to USUAL fails
            var count = block.Statements.Length;
            List <BoundStatement> newlist = new List <BoundStatement>();

            if (count == 0)
            {
                var result = new BoundDefaultExpression(block.Syntax, usualType);
                newlist.Add(new BoundReturnStatement(block.Syntax, RefKind.None, result));
                block = block.Update(block.Locals, ImmutableArray <LocalFunctionSymbol> .Empty, newlist.ToImmutableArray <BoundStatement>());
            }
            else
            {
                var stmt = block.Statements[count - 1];
                if (stmt is BoundReturnStatement && stmt.HasErrors)
                {
                    BoundExpression expr = (stmt as BoundReturnStatement).ExpressionOpt;
                    // when the last expression is a conversion to USUAL
                    // and there is an error, then this is most likely the conversion from
                    // a void to USUAL. When that happens, then create an extra stmt in the body of the lambda
                    // store the return expression in an expression statement
                    // and return a NIL
                    if (expr is BoundConversion)
                    {
                        var boundConv = expr as BoundConversion;
                        var operand   = boundConv.Operand;
                        if (boundConv.Type == usualType && operand.Type.SpecialType == SpecialType.System_Void)
                        {
                            diagnostics.Clear();
                            for (int i = 0; i < block.Statements.Length - 1; i++)
                            {
                                newlist.Add(block.Statements[i]);
                            }
                            newlist.Add(new BoundExpressionStatement(stmt.Syntax, operand));
                            var result = new BoundDefaultExpression(stmt.Syntax, usualType);
                            newlist.Add(new BoundReturnStatement(stmt.Syntax, RefKind.None, result));
                            block = new BoundBlock(block.Syntax, block.Locals, newlist.ToImmutableArray <BoundStatement>());
                        }
                    }
                }
            }
            return(block);
        }
예제 #4
0
 /// <summary>
 /// Removes all <see cref="Diagnostic"/>s that weren't logged using the <see cref="Push"/> method.
 /// </summary>
 public virtual void Clear()
 {
     _bag.Clear();
 }
예제 #5
0
        private bool Compile(
            string code,
            string path,
            DiagnosticBag diagnostics,
            Session session,
            Type delegateType,
            Type returnType,
            CancellationToken cancellationToken,
            bool isInteractive,
            bool isExecute,
            out CommonCompilation compilation,
            out Delegate factory)
        {
            Debug.Assert(delegateType != null);
            Debug.Assert(session != null);
            Debug.Assert(code != null);

            DiagnosticBag localDiagnostics = diagnostics ?? DiagnosticBag.GetInstance();
            IText         text             = new StringText(code);

            try
            {
                CommonCompilation localCompilation = CreateCompilation(text, path, isInteractive, session, returnType, localDiagnostics);
                if (localCompilation == null)
                {
                    Debug.Assert(localDiagnostics.HasAnyErrors());
                    CompilationError(localDiagnostics, diagnostics);
                    factory     = null;
                    compilation = null;
                    return(false);
                }

                // throw away all syntax warnings, they will be reported again by emit:
                localDiagnostics.Clear();

                // If we compile just in time for execution the user doesn't have access to the submission compilation just created.
                // If the previous submission hasn't been executed yet the execution would blow up when invoking the submission factory,
                // and after that the session would become unusable since there is no way how the user can re-execute the current submission.
                // So throw here before we save the submission into the session.
                if (isExecute)
                {
                    int slotIndex = localCompilation.GetSubmissionSlotIndex();
                    SessionHelpers.RequirePreviousSubmissionExecuted(session, slotIndex);
                }

                // TODO: (tomat)
                // Current CLR implementation of collectible assemblies doesn't support
                // references from uncollectible to collectible code.
                //
                // We can't emit collectible code if there is a possibility that we will
                // compile another submission in the session.
                //
                // A workaround might be to regenerate all collectible dependencies of an uncollectible
                // submission as uncollectible.
                //
                // For now we explicitly mark sessions as collectible in tests to keep test coverage.
                bool collectible = session.isCollectible;
                if (!TryEmitSubmission(localCompilation, localDiagnostics, delegateType, collectible, cancellationToken, out factory))
                {
                    Debug.Assert(localDiagnostics.HasAnyErrors());
                    CompilationError(localDiagnostics, diagnostics);
                    factory     = null;
                    compilation = null;
                    return(false);
                }

                session.SubmissionCompiled(localCompilation);

                compilation = localCompilation;
                return(true);
            }
            finally
            {
                if (localDiagnostics != diagnostics)
                {
                    localDiagnostics.Free();
                }
            }
        }