コード例 #1
0
        internal static SynthesizedEntryPointSymbol Create(SynthesizedInteractiveInitializerMethod initializerMethod, DiagnosticBag diagnostics)
        {
            var containingType = initializerMethod.ContainingType;
            var compilation    = containingType.DeclaringCompilation;

            if (compilation.IsSubmission)
            {
                var submissionArrayType = compilation.CreateArrayTypeSymbol(compilation.GetSpecialType(SpecialType.System_Object));
                ReportUseSiteDiagnostics(submissionArrayType, diagnostics);
                return(new SubmissionEntryPoint(
                           containingType,
                           initializerMethod.ReturnType,
                           submissionArrayType));
            }
            else
            {
                var taskType = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task);
#if DEBUG
                HashSet <DiagnosticInfo> useSiteDiagnostics = null;
                Debug.Assert(taskType.IsErrorType() || initializerMethod.ReturnType.IsDerivedFrom(taskType, TypeCompareKind.IgnoreDynamicAndTupleNames, useSiteDiagnostics: ref useSiteDiagnostics));
#endif
                ReportUseSiteDiagnostics(taskType, diagnostics);
                var getAwaiterMethod = taskType.IsErrorType() ?
                                       null :
                                       GetRequiredMethod(taskType, WellKnownMemberNames.GetAwaiter, diagnostics);
                var getResultMethod = ((object)getAwaiterMethod == null) ?
                                      null :
                                      GetRequiredMethod(getAwaiterMethod.ReturnType, WellKnownMemberNames.GetResult, diagnostics);
                return(new ScriptEntryPoint(
                           containingType,
                           compilation.GetSpecialType(SpecialType.System_Void),
                           getAwaiterMethod,
                           getResultMethod));
            }
        }
コード例 #2
0
        internal static SynthesizedEntryPointSymbol Create(SynthesizedInteractiveInitializerMethod initializerMethod, DiagnosticBag diagnostics)
        {
            var containingType = initializerMethod.ContainingType;
            var compilation = containingType.DeclaringCompilation;
            if (compilation.IsSubmission)
            {
                var submissionArrayType = compilation.CreateArrayTypeSymbol(compilation.GetSpecialType(SpecialType.System_Object));
                ReportUseSiteDiagnostics(submissionArrayType, diagnostics);
                return new SubmissionEntryPoint(
                    containingType,
                    initializerMethod.ReturnType,
                    submissionArrayType);
            }
            else
            {
                var taskType = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task);
#if DEBUG
                HashSet<DiagnosticInfo> useSiteDiagnostics = null;
                Debug.Assert(taskType.IsErrorType() || initializerMethod.ReturnType.IsDerivedFrom(taskType, ignoreDynamic: true, useSiteDiagnostics: ref useSiteDiagnostics));
#endif
                ReportUseSiteDiagnostics(taskType, diagnostics);
                var getAwaiterMethod = taskType.IsErrorType() ?
                    null :
                    GetRequiredMethod(taskType, WellKnownMemberNames.GetAwaiter, diagnostics);
                var getResultMethod = ((object)getAwaiterMethod == null) ?
                    null :
                    GetRequiredMethod(getAwaiterMethod.ReturnType, WellKnownMemberNames.GetResult, diagnostics);
                return new ScriptEntryPoint(
                    containingType,
                    compilation.GetSpecialType(SpecialType.System_Void),
                    getAwaiterMethod,
                    getResultMethod);
            }
        }
コード例 #3
0
        private static void SetScriptInitializerReturnType(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializer,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
            DiagnosticBag diagnostics)
        {
            bool isAsync = scriptInitializer.IsSubmissionInitializer && fieldInitializers.Any(i => i.Any(ContainsAwaitsVisitor.ContainsAwait));
            var resultType = scriptInitializer.ResultType;
            TypeSymbol returnType;

            if ((object)resultType == null)
            {
                Debug.Assert(!isAsync);
                returnType = compilation.GetSpecialType(SpecialType.System_Void);
            }
            else if (!isAsync)
            {
                returnType = resultType;
            }
            else
            {
                var taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T);
                var useSiteDiagnostic = taskT.GetUseSiteDiagnostic();
                if (useSiteDiagnostic != null)
                {
                    diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton);
                }
                returnType = taskT.Construct(resultType);
            }

            scriptInitializer.SetReturnType(isAsync, returnType);
        }
コード例 #4
0
        internal static SynthesizedEntryPointSymbol Create(
            SynthesizedInteractiveInitializerMethod initializerMethod,
            BindingDiagnosticBag diagnostics
            )
        {
            var containingType = initializerMethod.ContainingType;
            var compilation    = containingType.DeclaringCompilation;

            if (compilation.IsSubmission)
            {
                var systemObject = Binder.GetSpecialType(
                    compilation,
                    SpecialType.System_Object,
                    DummySyntax(),
                    diagnostics
                    );
                var submissionArrayType = compilation.CreateArrayTypeSymbol(systemObject);
                diagnostics.ReportUseSite(submissionArrayType, NoLocation.Singleton);
                return(new SubmissionEntryPoint(
                           containingType,
                           initializerMethod.ReturnTypeWithAnnotations,
                           submissionArrayType
                           ));
            }
            else
            {
                var systemVoid = Binder.GetSpecialType(
                    compilation,
                    SpecialType.System_Void,
                    DummySyntax(),
                    diagnostics
                    );
                return(new ScriptEntryPoint(containingType, TypeWithAnnotations.Create(systemVoid)));
            }
        }
コード例 #5
0
 private static ImmutableArray<LabelSymbol> GetLabels(SynthesizedInteractiveInitializerMethod scriptInitializer, CompilationUnitSyntax syntax)
 {
     var builder = ArrayBuilder<LabelSymbol>.GetInstance();
     foreach (var member in syntax.Members)
     {
         if (member.Kind() != SyntaxKind.GlobalStatement)
         {
             continue;
         }
         LocalScopeBinder.BuildLabels(scriptInitializer, ((GlobalStatementSyntax)member).Statement, ref builder);
     }
     return builder.ToImmutableAndFree();
 }
コード例 #6
0
ファイル: InitializerRewriter.cs プロジェクト: rgani/roslyn
        internal static BoundTypeOrInstanceInitializers RewriteScriptInitializer(ImmutableArray<BoundInitializer> boundInitializers, SynthesizedInteractiveInitializerMethod method, out bool hasTrailingExpression)
        {
            Debug.Assert(!boundInitializers.IsDefault);

            var boundStatements = ArrayBuilder<BoundStatement>.GetInstance(boundInitializers.Length);
            var submissionResultType = method.ResultType;
            var hasSubmissionResultType = (object)submissionResultType != null;
            BoundStatement lastStatement = null;
            BoundExpression trailingExpression = null;

            foreach (var initializer in boundInitializers)
            {
                // The value of the last expression statement (if any) is returned from the submission initializer,
                // unless this is a #load'ed tree.  I the #load'ed tree case, we'll execute the trailing expression
                // but discard its result.
                if (hasSubmissionResultType &&
                    (initializer == boundInitializers.Last()) &&
                    (initializer.Kind == BoundKind.GlobalStatementInitializer) &&
                    method.DeclaringCompilation.IsSubmissionSyntaxTree(initializer.SyntaxTree))
                {
                    lastStatement = ((BoundGlobalStatementInitializer)initializer).Statement;
                    var expression = GetTrailingScriptExpression(lastStatement);
                    if (expression != null &&
                        (object)expression.Type != null &&
                        expression.Type.SpecialType != SpecialType.System_Void)
                    {
                        trailingExpression = expression;
                        continue;
                    }
                }

                boundStatements.Add(RewriteInitializersAsStatements(initializer));
            }

            if (hasSubmissionResultType && (trailingExpression != null))
            {
                Debug.Assert(submissionResultType.SpecialType != SpecialType.System_Void);

                // Note: The trailing expression was already converted to the submission result type in Binder.BindGlobalStatement.
                boundStatements.Add(new BoundReturnStatement(lastStatement.Syntax, trailingExpression));
                hasTrailingExpression = true;
            }
            else
            {
                hasTrailingExpression = false;
            }

            return new BoundTypeOrInstanceInitializers(method.GetNonNullSyntaxNode(), boundStatements.ToImmutableAndFree());
        }
コード例 #7
0
 internal static void BindFieldInitializers(
     CSharpCompilation compilation,
     SynthesizedInteractiveInitializerMethod scriptInitializerOpt,
     ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
     DiagnosticBag diagnostics,
     ref ProcessedFieldInitializers processedInitializers)
 {
     var diagsForInstanceInitializers = DiagnosticBag.GetInstance();
     ImportChain firstImportChain;
     processedInitializers.BoundInitializers = BindFieldInitializers(compilation, scriptInitializerOpt, fieldInitializers, diagsForInstanceInitializers, out firstImportChain);
     processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
     processedInitializers.FirstImportChain = firstImportChain;
     diagnostics.AddRange(diagsForInstanceInitializers);
     diagsForInstanceInitializers.Free();
 }
コード例 #8
0
        internal static BoundTypeOrInstanceInitializers RewriteScriptInitializer(ImmutableArray<BoundInitializer> boundInitializers, SynthesizedInteractiveInitializerMethod method)
        {
            Debug.Assert(!boundInitializers.IsDefault);

            var boundStatements = ArrayBuilder<BoundStatement>.GetInstance(boundInitializers.Length);
            var submissionResultType = method.ResultType;
            BoundExpression submissionResult = null;

            foreach (var initializer in boundInitializers)
            {
                // The value of the last expression statement (if any) is returned from the submission initializer.
                if (((object)submissionResultType != null) &&
                    (initializer == boundInitializers.Last()) &&
                    (initializer.Kind == BoundKind.GlobalStatementInitializer))
                {
                    var statement = ((BoundGlobalStatementInitializer)initializer).Statement;
                    if (statement.Kind == BoundKind.ExpressionStatement)
                    {
                        var expr = ((BoundExpressionStatement)statement).Expression;
                        if ((object)expr.Type != null && expr.Type.SpecialType != SpecialType.System_Void)
                        {
                            submissionResult = expr;
                            continue;
                        }
                    }
                }
                boundStatements.Add(RewriteInitializersAsStatements(initializer));
            }

            var syntax = method.GetNonNullSyntaxNode();
            if ((object)submissionResultType != null)
            {
                if (submissionResult == null)
                {
                    // Return default(T) if submission does not have a trailing expression.
                    submissionResult = new BoundDefaultOperator(syntax, submissionResultType);
                }
                Debug.Assert(submissionResult.Type.SpecialType != SpecialType.System_Void);

                // The expression is converted to the submission result type when the initializer is bound.
                boundStatements.Add(new BoundReturnStatement(submissionResult.Syntax, submissionResult));
            }

            return new BoundTypeOrInstanceInitializers(syntax, boundStatements.ToImmutableAndFree());
        }
コード例 #9
0
        internal static void BindFieldInitializers(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializerOpt,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> fieldInitializers,
            DiagnosticBag diagnostics,
            bool setReturnType, // Remove once static fields are errors in submissions.
            ref ProcessedFieldInitializers processedInitializers)
        {
            if (setReturnType && ((object)scriptInitializerOpt != null))
            {
                SetScriptInitializerReturnType(compilation, scriptInitializerOpt, fieldInitializers, diagnostics);
            }

            var diagsForInstanceInitializers = DiagnosticBag.GetInstance();
            ImportChain firstImportChain;
            processedInitializers.BoundInitializers = BindFieldInitializers(compilation, scriptInitializerOpt, fieldInitializers, diagsForInstanceInitializers, out firstImportChain);
            processedInitializers.HasErrors = diagsForInstanceInitializers.HasAnyErrors();
            processedInitializers.FirstImportChain = firstImportChain;
            diagnostics.AddRange(diagsForInstanceInitializers);
            diagsForInstanceInitializers.Free();
        }
コード例 #10
0
        private static ImmutableArray<BoundInitializer> BindFieldInitializers(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializerOpt,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> initializers,
            DiagnosticBag diagnostics,
            out ImportChain firstImportChain)
        {
            if (initializers.IsEmpty)
            {
                firstImportChain = null;
                return ImmutableArray<BoundInitializer>.Empty;
            }

            var boundInitializers = ArrayBuilder<BoundInitializer>.GetInstance();
            if ((object)scriptInitializerOpt == null)
            {
                BindRegularCSharpFieldInitializers(compilation, initializers, boundInitializers, diagnostics, out firstImportChain);
            }
            else
            {
                BindScriptFieldInitializers(compilation, scriptInitializerOpt, initializers, boundInitializers, diagnostics, out firstImportChain);
            }
            return boundInitializers.ToImmutableAndFree();
        }
コード例 #11
0
        private static BoundInitializer BindGlobalStatement(
            Binder binder,
            SynthesizedInteractiveInitializerMethod scriptInitializer,
            StatementSyntax statementNode,
            DiagnosticBag diagnostics,
            bool isLast)
        {
            var statement = binder.BindStatement(statementNode, diagnostics);
            if (isLast && !statement.HasAnyErrors)
            {
                // the result of the last global expression is assigned to the result storage for submission result:
                if (binder.Compilation.IsSubmission)
                {
                    // insert an implicit conversion for the submission return type (if needed):
                    var expression = InitializerRewriter.GetTrailingScriptExpression(statement);
                    if (expression != null &&
                        ((object)expression.Type == null || expression.Type.SpecialType != SpecialType.System_Void))
                    {
                        var submissionResultType = scriptInitializer.ResultType;
                        expression = binder.GenerateConversionForAssignment(submissionResultType, expression, diagnostics);
                        statement = new BoundExpressionStatement(statement.Syntax, expression, expression.HasErrors);
                    }
                }

                // don't allow trailing expressions after labels (as in regular C#, labels must be followed by a statement):
                if (statement.Kind == BoundKind.LabeledStatement)
                {
                    var labeledStatementBody = ((BoundLabeledStatement)statement).Body;
                    while (labeledStatementBody.Kind == BoundKind.LabeledStatement)
                    {
                        labeledStatementBody = ((BoundLabeledStatement)labeledStatementBody).Body;
                    }

                    if (InitializerRewriter.GetTrailingScriptExpression(labeledStatementBody) != null)
                    {
                        Error(diagnostics, ErrorCode.ERR_SemicolonExpected, ((ExpressionStatementSyntax)labeledStatementBody.Syntax).SemicolonToken);
                    }
                }
            }

            return new BoundGlobalStatementInitializer(statementNode, statement);
        }
コード例 #12
0
        /// <summary>
        /// In script C#, some field initializers are assignments to fields and others are global
        /// statements.  There are no restrictions on accessing instance members.
        /// </summary>
        private static void BindScriptFieldInitializers(
            CSharpCompilation compilation,
            SynthesizedInteractiveInitializerMethod scriptInitializer,
            ImmutableArray<ImmutableArray<FieldOrPropertyInitializer>> initializers,
            ArrayBuilder<BoundInitializer> boundInitializers,
            DiagnosticBag diagnostics,
            out ImportChain firstDebugImports)
        {
            firstDebugImports = null;

            for (int i = 0; i < initializers.Length; i++)
            {
                ImmutableArray<FieldOrPropertyInitializer> siblingInitializers = initializers[i];

                // All sibling initializers share the same parent node and tree so we can reuse the binder 
                // factory across siblings.  Unfortunately, we cannot reuse the binder itself, because
                // individual fields might have their own binders (e.g. because of being declared unsafe).
                BinderFactory binderFactory = null;
                // Label instances must be shared across all global statements.
                ScriptLocalScopeBinder.Labels labels = null;

                for (int j = 0; j < siblingInitializers.Length; j++)
                {
                    var initializer = siblingInitializers[j];
                    var fieldSymbol = initializer.FieldOpt;

                    if ((object)fieldSymbol != null && fieldSymbol.IsConst)
                    {
                        // Constants do not need field initializers.
                        continue;
                    }

                    var syntaxRef = initializer.Syntax;
                    var syntaxTree = syntaxRef.SyntaxTree;
                    Debug.Assert(syntaxTree.Options.Kind != SourceCodeKind.Regular);

                    var syntax = (CSharpSyntaxNode)syntaxRef.GetSyntax();
                    var syntaxRoot = syntaxTree.GetCompilationUnitRoot();

                    if (binderFactory == null)
                    {
                        binderFactory = compilation.GetBinderFactory(syntaxTree);
                        labels = new ScriptLocalScopeBinder.Labels(scriptInitializer, syntaxRoot);
                    }

                    Binder scriptClassBinder = binderFactory.GetBinder(syntax);
                    Debug.Assert(((NamedTypeSymbol)scriptClassBinder.ContainingMemberOrLambda).IsScriptClass);

                    if (firstDebugImports == null)
                    {
                        firstDebugImports = scriptClassBinder.ImportChain;
                    }

                    Binder parentBinder = new ExecutableCodeBinder(
                        syntaxRoot,
                        scriptInitializer,
                        new ScriptLocalScopeBinder(labels, scriptClassBinder));

                    BoundInitializer boundInitializer;
                    if ((object)fieldSymbol != null)
                    {
                        boundInitializer = BindFieldInitializer(
                            parentBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.FieldInitializer, fieldSymbol),
                            fieldSymbol,
                            (EqualsValueClauseSyntax)syntax,
                            diagnostics);
                    }
                    else
                    {
                        boundInitializer = BindGlobalStatement(
                            parentBinder,
                            scriptInitializer,
                            (StatementSyntax)syntax,
                            diagnostics,
                            isLast: i == initializers.Length - 1 && j == siblingInitializers.Length - 1);
                    }

                    boundInitializers.Add(boundInitializer);
                }
            }
        }
コード例 #13
0
ファイル: Binder_Initializers.cs プロジェクト: nemec/roslyn
        private static BoundInitializer BindGlobalStatement(
            Binder binder,
            SynthesizedInteractiveInitializerMethod scriptInitializer,
            StatementSyntax statementNode,
            DiagnosticBag diagnostics,
            bool isLast)
        {
            BoundStatement boundStatement = binder.BindStatement(statementNode, diagnostics);

            // the result of the last global expression is assigned to the result storage for submission result:
            if (binder.Compilation.IsSubmission && isLast && !boundStatement.HasAnyErrors)
            {
                // insert an implicit conversion for the submission return type (if needed):
                var expression = InitializerRewriter.GetTrailingScriptExpression(boundStatement);
                if (expression != null &&
                    ((object)expression.Type == null || expression.Type.SpecialType != SpecialType.System_Void))
                {
                    var submissionResultType = scriptInitializer.ResultType;
                    expression = binder.GenerateConversionForAssignment(submissionResultType, expression, diagnostics);
                    boundStatement = new BoundExpressionStatement(boundStatement.Syntax, expression, expression.HasErrors);
                }
            }

            return new BoundGlobalStatementInitializer(statementNode, boundStatement);
        }
コード例 #14
0
 internal Labels(SynthesizedInteractiveInitializerMethod scriptInitializer, CompilationUnitSyntax syntax)
 {
     _scriptInitializer = scriptInitializer;
     _syntax = syntax;
 }