public override LambdaConversionResult IsAnonymousFunctionCompatibleWithType(UnboundLambda anonymousFunction, TypeSymbol type)
        {
            var res = base.IsAnonymousFunctionCompatibleWithType(anonymousFunction, type);

            if (res == LambdaConversionResult.BadTargetType && _binder.Compilation.Options.HasRuntime)
            {
                if (type == Compilation.CodeBlockType() || type == Compilation.UsualType() || type.IsObjectType())
                {
                    return(LambdaConversionResult.Success);
                }

                var conv = Compilation.ClassifyConversion(Compilation.CodeBlockType(), type);
                if (conv.Exists)
                {
                    return(LambdaConversionResult.Success);
                }
            }

            return(res);
        }
Exemple #2
0
        private BoundExpression BindCodeblock(SyntaxNode syntax, UnboundLambda unboundLambda, Conversion conversion, bool isCast, TypeSymbol destination, DiagnosticBag diagnostics)
        {
            if (!Compilation.Options.HasRuntime)
            {
                return(null);
            }
            var isCodeblock = syntax.XIsCodeBlock;

            if (!isCodeblock)
            {
                isCodeblock = !destination.IsDelegateType() && !destination.IsExpressionTree();
            }
            if (!isCodeblock)
            {
                return(null);
            }

            Conversion conv = Conversion.ImplicitReference;

            if (destination != Compilation.CodeBlockType() && !destination.IsObjectType())
            {
                HashSet <DiagnosticInfo> useSiteDiagnostics = null;
                conv = Conversions.ClassifyConversionFromType(Compilation.CodeBlockType(), destination, ref useSiteDiagnostics);
                diagnostics.Add(syntax, useSiteDiagnostics);
            }
            if (Compilation.Options.HasRuntime)
            {
                Debug.Assert(destination == Compilation.CodeBlockType() || conv.Exists);
            }
            if (!syntax.XIsCodeBlock && !Compilation.Options.MacroScript && !syntax.XNode.IsAliasExpression())
            {
                Error(diagnostics, ErrorCode.ERR_CodeblockWithLambdaSyntax, syntax);
            }

            AnonymousTypeManager manager = this.Compilation.AnonymousTypeManager;
            var delegateSignature        = new TypeSymbol[unboundLambda.ParameterCount + 1];
            var usualType = this.Compilation.UsualType();

            for (int i = 0; i < delegateSignature.Length; i++)
            {
                delegateSignature[i] = usualType;
            }
            NamedTypeSymbol cbType       = manager.ConstructCodeblockTypeSymbol(delegateSignature, syntax.Location);
            var             delType      = manager.GetCodeblockDelegateType(cbType);
            var             _boundLambda = unboundLambda.Bind(delType);

            diagnostics.AddRange(_boundLambda.Diagnostics);
            var cbDel = new BoundConversion(
                syntax,
                _boundLambda,
                conversion,
                @checked: false,
                explicitCastInCode: false,
                constantValueOpt: ConstantValue.NotAvailable,
                type: delType)
            {
                WasCompilerGenerated = unboundLambda.WasCompilerGenerated
            };
            var             cbSrc  = new BoundLiteral(syntax, ConstantValue.Create(syntax.XCodeBlockSource), Compilation.GetSpecialType(SpecialType.System_String));
            BoundExpression cbInst = new BoundAnonymousObjectCreationExpression(syntax,
                                                                                cbType.InstanceConstructors[0],
                                                                                new BoundExpression[] { cbDel, cbSrc }.ToImmutableArrayOrEmpty(),
                                                                                System.Collections.Immutable.ImmutableArray <BoundAnonymousPropertyDeclaration> .Empty, cbType)
            {
                WasCompilerGenerated = unboundLambda.WasCompilerGenerated
            };;

            if (conv != Conversion.ImplicitReference)
            {
                cbInst = new BoundConversion(syntax, cbInst, Conversion.ImplicitReference, false, false, ConstantValue.NotAvailable, Compilation.CodeBlockType())
                {
                    WasCompilerGenerated = unboundLambda.WasCompilerGenerated
                };;
            }
            if (!conv.IsValid || (!isCast && conv.IsExplicit))
            {
                GenerateImplicitConversionError(diagnostics, syntax, conv, cbInst, destination);

                return(new BoundConversion(
                           syntax,
                           cbInst,
                           conv,
                           false,
                           explicitCastInCode: isCast,
                           constantValueOpt: ConstantValue.NotAvailable,
                           type: destination,
                           hasErrors: true)
                {
                    WasCompilerGenerated = unboundLambda.WasCompilerGenerated
                });
            }
            return(new BoundConversion(
                       syntax,
                       cbInst,
                       conv,
                       false,
                       explicitCastInCode: isCast,
                       constantValueOpt: ConstantValue.NotAvailable,
                       type: destination)
            {
                WasCompilerGenerated = unboundLambda.WasCompilerGenerated
            });
        }