internal SpillFieldAllocator(SyntheticBoundNodeFactory F, TypeCompilationState CompilationState)
 {
     allocatedFields = new KeyedStack<TypeSymbol, FieldSymbol>();
     realizedSpills = new Dictionary<BoundSpillTemp, FieldSymbol>();
     this.F = F;
     this.CompilationState = CompilationState;
 }
コード例 #2
0
            internal SynthesizedLambdaMethod(NamedTypeSymbol containingType, MethodSymbol topLevelMethod, BoundLambda node, bool isStatic, TypeCompilationState compilationState)
                : base(containingType,
                       node.Symbol,
                       null,
                       node.SyntaxTree.GetReference(node.Body.Syntax),
                       node.Syntax.GetLocation(),
                       GeneratedNames.MakeLambdaMethodName(topLevelMethod.Name, compilationState.GenerateTempNumber()),
                       (containingType is LambdaFrame ? DeclarationModifiers.Internal : DeclarationModifiers.Private)
                            | (isStatic ? DeclarationModifiers.Static : 0)
                            | (node.Symbol.IsAsync ? DeclarationModifiers.Async : 0))
            {
                TypeMap typeMap;
                ImmutableArray<TypeParameterSymbol> typeParameters;
                LambdaFrame lambdaFrame;

                if (!topLevelMethod.IsGenericMethod)
                {
                    typeMap = TypeMap.Empty;
                    typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
                }
                else if ((object)(lambdaFrame = this.ContainingType as LambdaFrame) != null)
                {
                    typeMap = lambdaFrame.TypeMap;
                    typeParameters = ImmutableArray<TypeParameterSymbol>.Empty;
                }
                else
                {
                    typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out typeParameters);
                }

                AssignTypeMapAndTypeParameters(typeMap, typeParameters);
            }
コード例 #3
0
        protected StateMachineRewriter(
            BoundStatement body,
            MethodSymbol method,
            SynthesizedContainer stateMachineType,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(body != null);
            Debug.Assert(method != null);
            Debug.Assert(stateMachineType != null);
            Debug.Assert(compilationState != null);
            Debug.Assert(diagnostics != null);

            this.body = body;
            this.method = method;
            this.stateMachineType = stateMachineType;
            this.slotAllocatorOpt = slotAllocatorOpt;
            this.synthesizedLocalOrdinals = new SynthesizedLocalOrdinalsDispenser();
            this.diagnostics = diagnostics;

            this.F = new SyntheticBoundNodeFactory(method, body.Syntax, compilationState, diagnostics);
            Debug.Assert(F.CurrentType == method.ContainingType);
            Debug.Assert(F.Syntax == body.Syntax);
        }
コード例 #4
0
ファイル: IteratorRewriter.cs プロジェクト: pheede/roslyn
        /// <summary>
        /// Rewrite an iterator method into a state machine class.
        /// </summary>
        /// <param name="body">The original body of the method</param>
        /// <param name="method">The method's identity</param>
        /// <param name="compilationState">The collection of generated methods that result from this transformation and which must be emitted</param>
        /// <param name="diagnostics">Diagnostic bag for diagnostics.</param>
        /// <param name="generateDebugInfo"></param>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            bool generateDebugInfo)
        {
            TypeSymbol elementType = method.IteratorElementType;
            if ((object)elementType == null)
            {
                return body;
            }

            // Figure out what kind of iterator we are generating.
            bool isEnumerable;
            switch (method.ReturnType.OriginalDefinition.SpecialType)
            {
                case SpecialType.System_Collections_IEnumerable:
                case SpecialType.System_Collections_Generic_IEnumerable_T:
                    isEnumerable = true;
                    break;

                case SpecialType.System_Collections_IEnumerator:
                case SpecialType.System_Collections_Generic_IEnumerator_T:
                    isEnumerable = false;
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(method.ReturnType.OriginalDefinition.SpecialType);
            }

            var iteratorClass = new IteratorStateMachine(method, isEnumerable, elementType, compilationState);
            return new IteratorRewriter(body, method, isEnumerable, iteratorClass, compilationState, diagnostics, generateDebugInfo).Rewrite();
        }
コード例 #5
0
        internal static BoundBlock Rewrite(SourceMethodSymbol sourceMethodSymbol, MethodContractSyntax contract, BoundBlock body, TypeCompilationState compilationState, DiagnosticBag diagsForCurrentMethod)
        {
            var binder = compilationState.Compilation.GetBinderFactory(sourceMethodSymbol.SyntaxTree)
                                     .GetBinder(body.Syntax);
            SyntheticBoundNodeFactory factory = new SyntheticBoundNodeFactory(sourceMethodSymbol, sourceMethodSymbol.SyntaxNode, compilationState, diagsForCurrentMethod);
            var contractType = compilationState.Compilation.GetTypeByReflectionType(typeof(System.Diagnostics.Contracts.Contract), diagsForCurrentMethod);

            var contractStatements = ArrayBuilder<BoundStatement>.GetInstance(contract.Requires.Count);
            foreach (var requires in contract.Requires)
            {
                var condition = binder.BindExpression(requires.Condition, diagsForCurrentMethod);
                
                var methodCall = factory.StaticCall(contractType, "Requires", condition);
                var statement = factory.ExpressionStatement(methodCall);

                contractStatements.Add(statement);
            }
            foreach (var requires in contract.Ensures)
            {
                var condition = binder.BindExpression(requires.Condition, diagsForCurrentMethod);
                var methodCall = factory.StaticCall(contractType, "Ensures", condition);
                var statement = factory.ExpressionStatement(methodCall);

                contractStatements.Add(statement);
            }

            return body.Update(body.Locals, body.Statements.InsertRange(0, contractStatements.ToImmutableAndFree()));
        }
コード例 #6
0
ファイル: AsyncRewriter.cs プロジェクト: RoryVL/roslyn
        /// <summary>
        /// Rewrite an async method into a state machine type.
        /// </summary>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            int methodOrdinal,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            out AsyncStateMachine stateMachineType)
        {
            if (!method.IsAsync)
            {
                stateMachineType = null;
                return body;
            }

            // The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class.
            var typeKind = compilationState.Compilation.Options.EnableEditAndContinue ? TypeKind.Class : TypeKind.Struct;

            var bodyWithAwaitLifted = AwaitExpressionSpiller.Rewrite(body, method, compilationState, diagnostics);

            stateMachineType = new AsyncStateMachine(slotAllocatorOpt, compilationState, method, methodOrdinal, typeKind);
            compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType);
            var rewriter = new AsyncRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, slotAllocatorOpt, compilationState, diagnostics);

            if (!rewriter.VerifyPresenceOfRequiredAPIs())
            {
                return body;
            }

            return rewriter.Rewrite();
        }
コード例 #7
0
ファイル: AsyncRewriter.cs プロジェクト: EkardNT/Roslyn
        /// <summary>
        /// Rewrite an async method into a state machine class.
        /// </summary>
        /// <param name="body">The original body of the method</param>
        /// <param name="method">The method's identity</param>
        /// <param name="compilationState">The collection of generated methods that result from this transformation and which must be emitted</param>
        /// <param name="diagnostics">Diagnostic bag for diagnostics.</param>
        /// <param name="generateDebugInfo"></param>
        /// <param name="stateMachineType"></param>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            bool generateDebugInfo,
            out AsyncStateMachine stateMachineType)
        {
            if (!method.IsAsync)
            {
                stateMachineType = null;
                return body;
            }

            // The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class.
            var typeKind = compilationState.Compilation.Options.EnableEditAndContinue ? TypeKind.Class : TypeKind.Struct;

            var bodyWithAwaitLifted = AwaitLiftingRewriter.Rewrite(body, method, compilationState, diagnostics);

            stateMachineType = new AsyncStateMachine(method, typeKind);
            compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType);
            var rewriter = new AsyncRewriter(bodyWithAwaitLifted, method, stateMachineType, compilationState, diagnostics, generateDebugInfo);
            if (!rewriter.constructedSuccessfully)
            {
                return body;
            }

            return rewriter.Rewrite();
        }
コード例 #8
0
ファイル: AsyncStruct.cs プロジェクト: EkardNT/Roslyn
            public AsyncStruct(MethodSymbol method, TypeCompilationState compilationState)
                : base(method, GeneratedNames.MakeIteratorOrAsyncDisplayClassName(method.Name, compilationState.GenerateTempNumber()), TypeKind.Struct)
            {
                this.interfaces = ReadOnlyArray<NamedTypeSymbol>.CreateFrom(
                    compilationState.EmitModule.Compilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IAsyncStateMachine));

                this.constructor = new SynthesizedInstanceConstructor(this);
            }
コード例 #9
0
 private ExpressionLambdaRewriter(TypeCompilationState compilationState, CSharpSyntaxNode node, DiagnosticBag diagnostics)
 {
     Bound = new SyntheticBoundNodeFactory((NamedTypeSymbol)null, node, compilationState, diagnostics);
     Int32Type = Bound.SpecialType(SpecialType.System_Int32);
     ObjectType = Bound.SpecialType(SpecialType.System_Object);
     NullableType = Bound.SpecialType(SpecialType.System_Nullable_T);
     IEnumerableType = Bound.SpecialType(SpecialType.System_Collections_Generic_IEnumerable_T);
 }
コード例 #10
0
ファイル: AsyncStateMachine.cs プロジェクト: CAPCHIK/roslyn
 public AsyncStateMachine(VariableSlotAllocator variableAllocatorOpt, TypeCompilationState compilationState, MethodSymbol asyncMethod, int asyncMethodOrdinal, TypeKind typeKind)
     : base(variableAllocatorOpt, compilationState, asyncMethod, asyncMethodOrdinal)
 {
     // TODO: report use-site errors on these types
     _typeKind = typeKind;
     _interfaces = ImmutableArray.Create(asyncMethod.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_CompilerServices_IAsyncStateMachine));
     _constructor = new AsyncConstructor(this);
 }
コード例 #11
0
        private IteratorRewriter(
            BoundStatement body,
            MethodSymbol method,
            bool isEnumerable,
            IteratorStateMachine iteratorClass,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
            : base(body, method, iteratorClass, compilationState, diagnostics)
        {
            // the element type may contain method type parameters, which are now alpha-renamed into type parameters of the generated class
            this.elementType = iteratorClass.ElementType;

            this.isEnumerable = isEnumerable;
        }
コード例 #12
0
ファイル: AsyncRewriter.cs プロジェクト: Rickinio/roslyn
 private AsyncRewriter(
     BoundStatement body,
     MethodSymbol method,
     int methodOrdinal,
     AsyncStateMachine stateMachineType,
     VariableSlotAllocator slotAllocatorOpt,
     TypeCompilationState compilationState,
     DiagnosticBag diagnostics)
     : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics)
 {
     _constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection);
     _methodOrdinal = methodOrdinal;
     _ignoreAccessibility = compilationState.ModuleBuilderOpt.IgnoreAccessibility;
 }
コード例 #13
0
        private IteratorRewriter(
            BoundStatement body,
            MethodSymbol method,
            bool isEnumerable,
            IteratorStateMachine stateMachineType,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
            : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics)
        {
            // the element type may contain method type parameters, which are now alpha-renamed into type parameters of the generated class
            _elementType = stateMachineType.ElementType;

            _isEnumerable = isEnumerable;
        }
コード例 #14
0
 protected StateMachineRewriter(
     BoundStatement body,
     MethodSymbol method,
     SynthesizedContainer stateMachineClass,
     TypeCompilationState compilationState,
     DiagnosticBag diagnostics)
 {
     this.body = body;
     this.method = method;
     this.stateMachineClass = stateMachineClass;
     this.compilationState = compilationState;
     this.diagnostics = diagnostics;
     this.F = new SyntheticBoundNodeFactory(method, body.Syntax, compilationState, diagnostics);
     Debug.Assert(F.CurrentClass == method.ContainingType);
     Debug.Assert(F.Syntax == body.Syntax);
 }
コード例 #15
0
 private AsyncRewriter(
     BoundStatement body,
     MethodSymbol method,
     AsyncStateMachine stateMachineClass,
     TypeCompilationState compilationState,
     DiagnosticBag diagnostics)
     : base(body, method, stateMachineClass, compilationState, diagnostics)
 {
     try
     {
         constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineClass.TypeMap, out this.asyncMethodBuilderMemberCollection);
     }
     catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
     {
         diagnostics.Add(ex.Diagnostic);
         constructedSuccessfully = false;
     }
 }
コード例 #16
0
ファイル: IteratorClass.cs プロジェクト: riversky/roslyn
            public IteratorClass(MethodSymbol method, bool isEnumerable, TypeSymbol elementType, TypeCompilationState compilationState)
                : base(method, GeneratedNames.MakeIteratorOrAsyncDisplayClassName(method.Name, compilationState.GenerateTempNumber()), TypeKind.Class)
            {
                this.ElementType = TypeMap.SubstituteType(elementType);
                var interfaces = ArrayBuilder<NamedTypeSymbol>.GetInstance();
                if (isEnumerable)
                {
                    interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).Construct(ElementType));
                    interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_IEnumerable));
                }

                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerator_T).Construct(ElementType));
                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_IDisposable));
                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_IEnumerator));
                this.interfaces = interfaces.ToImmutableAndFree();

                this.constructor = new IteratorConstructor(this);
            }
コード例 #17
0
ファイル: IteratorRewriter.cs プロジェクト: Rickinio/roslyn
        /// <summary>
        /// Rewrite an iterator method into a state machine class.
        /// </summary>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            int methodOrdinal,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            out IteratorStateMachine stateMachineType)
        {
            TypeSymbol elementType = method.IteratorElementType;
            if ((object)elementType == null)
            {
                stateMachineType = null;
                return body;
            }

            // Figure out what kind of iterator we are generating.
            bool isEnumerable;
            switch (method.ReturnType.OriginalDefinition.SpecialType)
            {
                case SpecialType.System_Collections_IEnumerable:
                case SpecialType.System_Collections_Generic_IEnumerable_T:
                    isEnumerable = true;
                    break;

                case SpecialType.System_Collections_IEnumerator:
                case SpecialType.System_Collections_Generic_IEnumerator_T:
                    isEnumerable = false;
                    break;

                default:
                    throw ExceptionUtilities.UnexpectedValue(method.ReturnType.OriginalDefinition.SpecialType);
            }

            stateMachineType = new IteratorStateMachine(slotAllocatorOpt, compilationState, method, methodOrdinal, isEnumerable, elementType);
            compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType);
            var rewriter = new IteratorRewriter(body, method, isEnumerable, stateMachineType, slotAllocatorOpt, compilationState, diagnostics);
            if (!rewriter.VerifyPresenceOfRequiredAPIs())
            {
                return body;
            }

            return rewriter.Rewrite();
        }
コード例 #18
0
        public IteratorStateMachine(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, MethodSymbol iteratorMethod, int iteratorMethodOrdinal, bool isEnumerable, TypeSymbol elementType)
            : base(slotAllocatorOpt, compilationState, iteratorMethod, iteratorMethodOrdinal)
        {
            this.ElementType = TypeMap.SubstituteType(elementType);

            var interfaces = ArrayBuilder<NamedTypeSymbol>.GetInstance();
            if (isEnumerable)
            {
                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).Construct(ElementType));
                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_IEnumerable));
            }

            interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerator_T).Construct(ElementType));
            interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_IDisposable));
            interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_IEnumerator));
            _interfaces = interfaces.ToImmutableAndFree();

            _constructor = new IteratorConstructor(this);
        }
コード例 #19
0
ファイル: AsyncRewriter2.cs プロジェクト: riversky/roslyn
        /// <summary>
        /// Rewrite an async method into a state machine class.
        /// </summary>
        /// <param name="body">The original body of the method</param>
        /// <param name="method">The method's identity</param>
        /// <param name="compilationState">The collection of generated methods that result from this transformation and which must be emitted</param>
        /// <param name="diagnostics">Diagnostic bag for diagnostics.</param>
        /// <param name="generateDebugInfo"></param>
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics,
            bool generateDebugInfo)
        {
            if (!method.IsAsync)
            {
                return body;
            }

            var bodyWithAwaitLifted = AwaitLiftingRewriter.Rewrite(body, method, compilationState, diagnostics);
            var rewriter = new AsyncRewriter2(bodyWithAwaitLifted, method, ((SourceMethodSymbol)method).AsyncStateMachineType, compilationState, diagnostics, generateDebugInfo);
            if (!rewriter.constructedSuccessfully)
            {
                return body;
            }

            var bodyReplacement = rewriter.Rewrite();
            return bodyReplacement;
        }
コード例 #20
0
ファイル: AsyncRewriter.cs プロジェクト: RoryVL/roslyn
        private AsyncRewriter(
            BoundStatement body,
            MethodSymbol method,
            int methodOrdinal,
            AsyncStateMachine stateMachineType,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
            : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics)
        {
            try
            {
                _constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                _constructedSuccessfully = false;
            }

            _methodOrdinal = methodOrdinal;
            _ignoreAccessibility = compilationState.ModuleBuilderOpt.IgnoreAccessibility;
        }
コード例 #21
0
        // NOTE: can return null if the method has no body.
        internal static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList<Imports> debugImports)
        {
            debugImports = null;

            BoundStatement constructorInitializer = null;
            BoundBlock body;

            var compilation = method.DeclaringCompilation;

            var sourceMethod = method as SourceMethodSymbol;
            if ((object)sourceMethod != null)
            {
                if (sourceMethod.IsExtern)
                {
                    if (sourceMethod.BlockSyntax == null)
                    {
                        // Generate warnings only if we are not generating ERR_ExternHasBody error
                        GenerateExternalMethodWarnings(sourceMethod, diagnostics);
                    }
                    return null;
                }
                else if (sourceMethod.IsParameterlessValueTypeConstructor(requireSynthesized: true))
                {
                    // No body for default struct constructor.
                    return null;
                }

                var blockSyntax = sourceMethod.BlockSyntax;
                if (blockSyntax != null)
                {
                var factory = compilation.GetBinderFactory(sourceMethod.SyntaxTree);
                var inMethodBinder = factory.GetBinder(blockSyntax);
                var binder = new ExecutableCodeBinder(blockSyntax, sourceMethod, inMethodBinder);
                body = binder.BindBlock(blockSyntax, diagnostics);
                if (generateDebugInfo)
                {
                    debugImports = binder.ImportsList;
                }
                if (inMethodBinder.IsDirectlyInIterator)
                {
                    foreach (var parameter in method.Parameters)
                    {
                        if (parameter.RefKind != RefKind.None)
                        {
                            diagnostics.Add(ErrorCode.ERR_BadIteratorArgType, parameter.Locations[0]);
                        }
                        else if (parameter.Type.IsUnsafe())
                        {
                            diagnostics.Add(ErrorCode.ERR_UnsafeIteratorArgType, parameter.Locations[0]);
                        }
                    }

                    if (sourceMethod.IsUnsafe && compilation.Options.AllowUnsafe) // Don't cascade
                    {
                        diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, sourceMethod.Locations[0]);
                    }

                    if (sourceMethod.IsVararg)
                    {
                        // error CS1636: __arglist is not allowed in the parameter list of iterators
                        diagnostics.Add(ErrorCode.ERR_VarargsIterator, sourceMethod.Locations[0]);
                    }
                    }
                }
                else // for [if (blockSyntax != null)]
                {
                    var property = sourceMethod.AssociatedSymbol as SourcePropertySymbol;
                    if ((object)property != null && property.IsAutoProperty)
                    {
                        return MethodBodySynthesizer.ConstructAutoPropertyAccessorBody(sourceMethod);
                }

                    if (sourceMethod.IsPrimaryCtor)
                    {
                        body = null;
            }
            else
            {
                        return null;
                    }
                }
            }
            else
            {
                //  synthesized methods should return their bound bodies 
                body = null;
            }

            // delegates have constructors but not constructor initializers
            if (method.MethodKind == MethodKind.Constructor && !method.ContainingType.IsDelegateType())
            {
                var initializerInvocation = BindConstructorInitializer(method, diagnostics, compilation);

                if (initializerInvocation != null)
                {
                    constructorInitializer = new BoundExpressionStatement(initializerInvocation.Syntax, initializerInvocation) { WasCompilerGenerated = true };
                    Debug.Assert(initializerInvocation.HasAnyErrors || constructorInitializer.IsConstructorInitializer(), "Please keep this bound node in sync with BoundNodeExtensions.IsConstructorInitializer.");
                }
            }

            var statements = ArrayBuilder<BoundStatement>.GetInstance();

            if (constructorInitializer != null)
            {
                statements.Add(constructorInitializer);
            }

            if ((object)sourceMethod != null && sourceMethod.IsPrimaryCtor && (object)((SourceMemberContainerTypeSymbol)sourceMethod.ContainingType).PrimaryCtor == (object)sourceMethod)
            {
                Debug.Assert(method.MethodKind == MethodKind.Constructor && !method.ContainingType.IsDelegateType());
                Debug.Assert(body == null);

                if (sourceMethod.ParameterCount > 0)
                {
                    var factory = new SyntheticBoundNodeFactory(sourceMethod, sourceMethod.SyntaxNode, compilationState, diagnostics);
                    factory.CurrentMethod = sourceMethod; 

                    foreach (var parameter in sourceMethod.Parameters)
                    {
                        FieldSymbol field = parameter.PrimaryConstructorParameterBackingField;

                        if ((object)field != null)
                        {
                            statements.Add(factory.Assignment(factory.Field(factory.This(), field),
                                                                   factory.Parameter(parameter)));
                        }
                    }
                }
            }

            if (body != null)
            {
                statements.Add(body);
            }

            CSharpSyntaxNode syntax = body != null ? body.Syntax : method.GetNonNullSyntaxNode();

            BoundBlock block;
            if (statements.Count == 1 && statements[0].Kind == ((body == null) ? BoundKind.Block : body.Kind))
            {
                // most common case - we just have a single block for the body.
                block = (BoundBlock)statements[0];
                statements.Free();
            }
            else
            {
                block = new BoundBlock(syntax, default(ImmutableArray<LocalSymbol>), statements.ToImmutableAndFree()) { WasCompilerGenerated = true };
            }

            return method.MethodKind == MethodKind.Destructor ? MethodBodySynthesizer.ConstructDestructorBody(syntax, method, block) : block;
        }
コード例 #22
0
 internal static BoundStatement Rewrite(BoundStatement body, MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics)
 {
     return(new AwaitLiftingRewriter(method, body.Syntax, compilationState, diagnostics).Rewrite(body));
 }
コード例 #23
0
 /// <summary>
 /// Create a bound node factory. Note that the use of the factory to get special or well-known members
 /// that do not exist will result in an exception of type <see cref="MissingPredefinedMember"/> being thrown.
 /// </summary>
 /// <param name="topLevelMethod">The top-level method that will contain the code</param>
 /// <param name="node">The syntax node to which generated code should be attributed</param>
 /// <param name="compilationState">The state of compilation of the enclosing type</param>
 /// <param name="diagnostics">A bag where any diagnostics should be output</param>
 public SyntheticBoundNodeFactory(MethodSymbol topLevelMethod, CSharpSyntaxNode node, TypeCompilationState compilationState, DiagnosticBag diagnostics)
     : this(topLevelMethod, topLevelMethod.ContainingType, node, compilationState, diagnostics)
 {
 }
コード例 #24
0
        internal static BoundStatement LowerStatement(
            bool generateDebugInfo,
            MethodSymbol method,
            BoundStatement body,
            SynthesizedSubmissionFields previousSubmissionFields,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
        {
            if (body.HasErrors)
            {
                return body;
            }

            bool sawLambdas;
            bool sawDynamicOperations;
            bool sawAwaitInExceptionHandler;
            var loweredBody = LocalRewriter.Rewrite(
                method.DeclaringCompilation,
                generateDebugInfo,
                method,
                method.ContainingType,
                body,
                compilationState,
                diagnostics,
                previousSubmissionFields,
                out sawLambdas,
                out sawDynamicOperations,
                out sawAwaitInExceptionHandler);

            if (sawDynamicOperations && compilationState.ModuleBuilder.IsENCDelta)
            {
                // Dynamic operations are not supported in ENC.
                var location = method.Locations[0];
                diagnostics.Add(new CSDiagnosticInfo(ErrorCode.ERR_EnCNoDynamicOperation), location);
            }

            if (loweredBody.HasErrors)
            {
                return loweredBody;
            }

            if (sawAwaitInExceptionHandler)
            {
                // If we have awaits in handlers, we need to 
                // replace handlers with synthetic ones which can be consumed by async rewriter.
                // The reason why this rewrite happens before the lambda rewrite 
                // is that we may need access to exception locals and it would be fairly hard to do
                // if these locals are captured into closures (possibly nested ones).
                Debug.Assert(method.IteratorElementType == null);
                loweredBody = AsyncHandlerRewriter.Rewrite(
                    generateDebugInfo,
                    method,
                    method.ContainingType,
                    loweredBody,
                    compilationState,
                    diagnostics);
            }

            if (loweredBody.HasErrors)
            {
                return loweredBody;
            }

            BoundStatement bodyWithoutLambdas = loweredBody;
            if (sawLambdas)
            {
                LambdaRewriter.Analysis lambdaAnalysis = LambdaRewriter.Analysis.Analyze(loweredBody, method, out sawLambdas);
                if (sawLambdas)
                {
                    bodyWithoutLambdas = LambdaRewriter.Rewrite(loweredBody, method.ContainingType, method.ThisParameter, method, compilationState, diagnostics, lambdaAnalysis, generateDebugInfo);
                }
            }

            if (bodyWithoutLambdas.HasErrors)
            {
                return bodyWithoutLambdas;
            }

            BoundStatement bodyWithoutIterators = IteratorRewriter.Rewrite(bodyWithoutLambdas, method, compilationState, diagnostics, generateDebugInfo);

            if (bodyWithoutIterators.HasErrors)
            {
                return bodyWithoutIterators;
            }

            BoundStatement bodyWithoutAsync = AsyncRewriter2.Rewrite(bodyWithoutIterators, method, compilationState, diagnostics, generateDebugInfo);

            return bodyWithoutAsync;
        }
コード例 #25
0
        internal static BoundStatement Rewrite(
            BoundStatement body,
            MethodSymbol method,
            int methodOrdinal,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            BindingDiagnosticBag diagnostics,
            out IteratorStateMachine stateMachineType
            )
        {
            TypeWithAnnotations elementType = method.IteratorElementTypeWithAnnotations;

            if (elementType.IsDefault || method.IsAsync)
            {
                stateMachineType = null;
                return(body);
            }

            // Figure out what kind of iterator we are generating.
            bool isEnumerable;

            switch (method.ReturnType.OriginalDefinition.SpecialType)
            {
            case SpecialType.System_Collections_IEnumerable:
            case SpecialType.System_Collections_Generic_IEnumerable_T:
                isEnumerable = true;
                break;

            case SpecialType.System_Collections_IEnumerator:
            case SpecialType.System_Collections_Generic_IEnumerator_T:
                isEnumerable = false;
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(
                          method.ReturnType.OriginalDefinition.SpecialType
                          );
            }

            stateMachineType = new IteratorStateMachine(
                slotAllocatorOpt,
                compilationState,
                method,
                methodOrdinal,
                isEnumerable,
                elementType
                );
            compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(
                method,
                stateMachineType
                );
            var rewriter = new IteratorRewriter(
                body,
                method,
                isEnumerable,
                stateMachineType,
                slotAllocatorOpt,
                compilationState,
                diagnostics
                );

            if (!rewriter.VerifyPresenceOfRequiredAPIs())
            {
                return(body);
            }

            return(rewriter.Rewrite());
        }
コード例 #26
0
        internal static BoundStatement LowerStatement(
            bool generateDebugInfo,
            NamedTypeSymbol thisType,
            ParameterSymbol thisParameter,
            MethodSymbol method,
            BoundStatement body,
            SynthesizedSubmissionFields previousSubmissionFields,
            TypeCompilationState compilationState,
            DiagnosticBag diagnostics)
        {
            if (body.HasErrors)
            {
                return(body);
            }

            bool sawLambdas;
            bool sawDynamicOperations;
            bool sawAwaitInExceptionHandler;
            var  loweredBody = LocalRewriter.Rewrite(
                generateDebugInfo,
                method,
                method.ContainingType,
                body,
                compilationState,
                diagnostics,
                previousSubmissionFields,
                out sawLambdas,
                out sawDynamicOperations,
                out sawAwaitInExceptionHandler);

            if (sawDynamicOperations && compilationState.ModuleBuilder.IsENCDelta)
            {
                // Dynamic operations are not supported in ENC.
                var location = method.Locations[0];
                diagnostics.Add(new CSDiagnosticInfo(ErrorCode.ERR_EnCNoDynamicOperation), location);
            }

            if (loweredBody.HasErrors)
            {
                return(loweredBody);
            }

            if (sawAwaitInExceptionHandler)
            {
                // If we have awaits in handlers, we need to
                // replace handlers with synthetic ones which can be consumed by async rewriter.
                // The reason why this rewrite happens before the lambda rewrite
                // is that we may need access to exception locals and it would be fairly hard to do
                // if these locals are captured into closures (possibly nested ones).
                Debug.Assert(method.IteratorElementType == null);
                loweredBody = AsyncHandlerRewriter.Rewrite(
                    generateDebugInfo,
                    method,
                    method.ContainingType,
                    loweredBody,
                    compilationState,
                    diagnostics);
            }

            if (loweredBody.HasErrors)
            {
                return(loweredBody);
            }

            BoundStatement bodyWithoutLambdas = loweredBody;

            if (sawLambdas)
            {
                LambdaRewriter.Analysis lambdaAnalysis = LambdaRewriter.Analysis.Analyze(loweredBody, method, out sawLambdas);
                if (sawLambdas)
                {
                    bodyWithoutLambdas = LambdaRewriter.Rewrite(loweredBody, thisType, thisParameter, method, compilationState, diagnostics, lambdaAnalysis, generateDebugInfo);
                }
            }

            if (bodyWithoutLambdas.HasErrors)
            {
                return(bodyWithoutLambdas);
            }

            BoundStatement bodyWithoutIterators = IteratorRewriter.Rewrite(bodyWithoutLambdas, method, compilationState, diagnostics, generateDebugInfo);

            if (bodyWithoutIterators.HasErrors)
            {
                return(bodyWithoutIterators);
            }

            BoundStatement bodyWithoutAsync = AsyncRewriter2.Rewrite(bodyWithoutIterators, method, compilationState, diagnostics, generateDebugInfo);

            return(bodyWithoutAsync);
        }
コード例 #27
0
        internal static BoundStatement Rewrite(
            BoundStatement bodyWithAwaitLifted,
            MethodSymbol method,
            int methodOrdinal,
            VariableSlotAllocator slotAllocatorOpt,
            TypeCompilationState compilationState,
            BindingDiagnosticBag diagnostics,
            out AsyncStateMachine stateMachineType
            )
        {
            if (!method.IsAsync)
            {
                stateMachineType = null;
                return(bodyWithAwaitLifted);
            }

            CSharpCompilation compilation      = method.DeclaringCompilation;
            bool isAsyncEnumerableOrEnumerator =
                method.IsAsyncReturningIAsyncEnumerable(compilation) ||
                method.IsAsyncReturningIAsyncEnumerator(compilation);

            if (isAsyncEnumerableOrEnumerator && !method.IsIterator)
            {
                bool containsAwait = AwaitDetector.ContainsAwait(bodyWithAwaitLifted);
                diagnostics.Add(
                    containsAwait
                      ? ErrorCode.ERR_PossibleAsyncIteratorWithoutYield
                      : ErrorCode.ERR_PossibleAsyncIteratorWithoutYieldOrAwait,
                    method.Locations[0],
                    method.ReturnTypeWithAnnotations
                    );

                stateMachineType = null;
                return(bodyWithAwaitLifted);
            }

            // The CLR doesn't support adding fields to structs, so in order to enable EnC in an async method we need to generate a class.
            // For async-iterators, we also need to generate a class.
            var typeKind =
                (compilationState.Compilation.Options.EnableEditAndContinue || method.IsIterator)
                    ? TypeKind.Class
                    : TypeKind.Struct;

            stateMachineType = new AsyncStateMachine(
                slotAllocatorOpt,
                compilationState,
                method,
                methodOrdinal,
                typeKind
                );
            compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(
                method,
                stateMachineType
                );

            AsyncRewriter rewriter = isAsyncEnumerableOrEnumerator
                ? new AsyncIteratorRewriter(
                bodyWithAwaitLifted,
                method,
                methodOrdinal,
                stateMachineType,
                slotAllocatorOpt,
                compilationState,
                diagnostics
                )
                : new AsyncRewriter(
                bodyWithAwaitLifted,
                method,
                methodOrdinal,
                stateMachineType,
                slotAllocatorOpt,
                compilationState,
                diagnostics
                );

            if (!rewriter.VerifyPresenceOfRequiredAPIs())
            {
                return(bodyWithAwaitLifted);
            }

            try
            {
                return(rewriter.Rewrite());
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                return(new BoundBadStatement(
                           bodyWithAwaitLifted.Syntax,
                           ImmutableArray.Create <BoundNode>(bodyWithAwaitLifted),
                           hasErrors: true
                           ));
            }
        }
コード例 #28
0
 internal LambdaFrame(MethodSymbol topLevelMethod, TypeCompilationState compilationState)
     : base(topLevelMethod, GeneratedNames.MakeAnonymousDisplayClassName(compilationState.GenerateTempNumber()), TypeKind.Class)
 {
     this.constructor = new SynthesizedInstanceConstructor(this);
 }
コード例 #29
0
 public StateMachineTypeSymbol(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, MethodSymbol kickoffMethod, int kickoffMethodOrdinal)
     : base(MakeName(slotAllocatorOpt, compilationState, kickoffMethod, kickoffMethodOrdinal), kickoffMethod)
 {
     Debug.Assert(kickoffMethod != null);
     this.KickoffMethod = kickoffMethod;
 }
コード例 #30
0
 private static string MakeName(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, MethodSymbol kickoffMethod, int kickoffMethodOrdinal)
 {
     return(slotAllocatorOpt?.PreviousStateMachineTypeName ??
            GeneratedNames.MakeStateMachineTypeName(kickoffMethod.Name, kickoffMethodOrdinal, compilationState.ModuleBuilderOpt.CurrentGenerationOrdinal));
 }
コード例 #31
0
ファイル: FlowAnalysisPass.cs プロジェクト: zdybai/roslyn
        public static BoundBlock Rewrite(
            MethodSymbol method,
            BoundBlock block,
            TypeCompilationState compilationState,
            BindingDiagnosticBag diagnostics,
            bool hasTrailingExpression,
            bool originalBodyNested)
        {
#if DEBUG
            // We should only see a trailingExpression if we're in a Script initializer.
            Debug.Assert(!hasTrailingExpression || method.IsScriptInitializer);
            var initialDiagnosticCount = diagnostics.ToReadOnly().Diagnostics.Length;
#endif
            var compilation = method.DeclaringCompilation;

            if (method.ReturnsVoid || method.IsIterator || method.IsAsyncEffectivelyReturningTask(compilation))
            {
                ImmutableArray <FieldSymbol> implicitlyInitializedFields = default;
                bool needsImplicitReturn = true;
                // we don't analyze synthesized void methods.
                if ((method.IsImplicitlyDeclared && !method.IsScriptInitializer) ||
                    Analyze(compilation, method, block, diagnostics.DiagnosticBag, out needsImplicitReturn, out implicitlyInitializedFields))
                {
                    if (!implicitlyInitializedFields.IsDefault)
                    {
                        Debug.Assert(!implicitlyInitializedFields.IsEmpty);
                        block = PrependImplicitInitializations(block, method, implicitlyInitializedFields, compilationState, diagnostics);
                    }
                    if (needsImplicitReturn)
                    {
                        block = AppendImplicitReturn(block, method, originalBodyNested);
                    }
                }
            }
            else if (Analyze(compilation, method, block, diagnostics.DiagnosticBag, out var needsImplicitReturn, out var unusedImplicitlyInitializedFields))
            {
                Debug.Assert(unusedImplicitlyInitializedFields.IsDefault);
                Debug.Assert(needsImplicitReturn);
                // If the method is a lambda expression being converted to a non-void delegate type
                // and the end point is reachable then suppress the error here; a special error
                // will be reported by the lambda binder.
                Debug.Assert(method.MethodKind != MethodKind.AnonymousFunction);

                // Add implicit "return default(T)" if this is a submission that does not have a trailing expression.
                var submissionResultType = (method as SynthesizedInteractiveInitializerMethod)?.ResultType;
                if (!hasTrailingExpression && ((object)submissionResultType != null))
                {
                    Debug.Assert(!submissionResultType.IsVoidType());

                    var trailingExpression = new BoundDefaultExpression(method.GetNonNullSyntaxNode(), submissionResultType);
                    var newStatements      = block.Statements.Add(new BoundReturnStatement(trailingExpression.Syntax, RefKind.None, trailingExpression, @checked: false));
                    block = new BoundBlock(block.Syntax, ImmutableArray <LocalSymbol> .Empty, newStatements)
                    {
                        WasCompilerGenerated = true
                    };
#if DEBUG
                    // It should not be necessary to repeat analysis after adding this node, because adding a trailing
                    // return in cases where one was missing should never produce different Diagnostics.
                    IEnumerable <Diagnostic> getErrorsOnly(IEnumerable <Diagnostic> diags) => diags.Where(d => d.Severity == DiagnosticSeverity.Error);

                    var flowAnalysisDiagnostics = DiagnosticBag.GetInstance();
                    Debug.Assert(!Analyze(compilation, method, block, flowAnalysisDiagnostics, needsImplicitReturn: out _, out unusedImplicitlyInitializedFields));
                    Debug.Assert(unusedImplicitlyInitializedFields.IsDefault);
                    // Ignore warnings since flow analysis reports nullability mismatches.
                    Debug.Assert(getErrorsOnly(flowAnalysisDiagnostics.ToReadOnly()).SequenceEqual(getErrorsOnly(diagnostics.ToReadOnly().Diagnostics.Skip(initialDiagnosticCount))));
                    flowAnalysisDiagnostics.Free();
#endif
                }
                // If there's more than one location, then the method is partial and we
                // have already reported a non-void partial method error.
                else if (method.Locations.Length == 1)
                {
                    diagnostics.Add(ErrorCode.ERR_ReturnExpected, method.Locations[0], method);
                }
            }

            return(block);
        }
コード例 #32
0
ファイル: FlowAnalysisPass.cs プロジェクト: zdybai/roslyn
        private static BoundBlock PrependImplicitInitializations(BoundBlock body, MethodSymbol method, ImmutableArray <FieldSymbol> implicitlyInitializedFields, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(method.MethodKind == MethodKind.Constructor);
            Debug.Assert(method.ContainingType.IsStructType());

            var syntax = body.Syntax;
            var F      = new SyntheticBoundNodeFactory(method, syntax, compilationState, diagnostics);

            var builder = ArrayBuilder <BoundStatement> .GetInstance(implicitlyInitializedFields.Length + 1);

            foreach (var field in implicitlyInitializedFields)
            {
                builder.Add(new BoundExpressionStatement(
                                syntax,
                                F.AssignmentExpression(
                                    F.Field(F.This(), field),
                                    F.Default(field.Type))));
            }
            builder.Add(body);

            return(BoundBlock.SynthesizedNoLocals(syntax, builder.ToImmutableAndFree()));
        }
コード例 #33
0
        private static BoundBlock PrependImplicitInitializations(BoundBlock body, MethodSymbol method, ImmutableArray <FieldSymbol> implicitlyInitializedFields, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(method.MethodKind == MethodKind.Constructor);
            Debug.Assert(method.ContainingType.IsStructType());

            var F = new SyntheticBoundNodeFactory(method, body.Syntax, compilationState, diagnostics);

            var builder = ArrayBuilder <BoundStatement> .GetInstance(implicitlyInitializedFields.Length);

            foreach (var field in implicitlyInitializedFields)
            {
                builder.Add(
                    F.ExpressionStatement(
                        F.AssignmentExpression(
                            F.Field(F.This(), field),
                            F.Default(field.Type))));
            }
            var initializations = F.HiddenSequencePoint(F.Block(builder.ToImmutableAndFree()));

            return(body.Update(body.Locals, body.LocalFunctions, body.Statements.Insert(index: 0, initializations)));
        }
コード例 #34
0
        internal static MethodBody GenerateMethodBody(TypeCompilationState compilationState, MethodSymbol method, BoundStatement block, DiagnosticBag diagnostics,
                                                      bool optimize, DebugDocumentProvider debugDocumentProvider, ImmutableArray <NamespaceScope> namespaceScopes)
        {
            // Note: don't call diagnostics.HasAnyErrors() in release; could be expensive if compilation has many warnings.
            Debug.Assert(!diagnostics.HasAnyErrors(), "Running code generator when errors exist might be dangerous; code generator not well hardened");

            bool emitSequencePoints = !namespaceScopes.IsDefault && !method.IsAsync;
            var  module             = compilationState.ModuleBuilder;
            var  compilation        = module.Compilation;
            var  localSlotManager   = module.CreateLocalSlotManager(method);

            ILBuilder     builder = new ILBuilder(module, localSlotManager, optimize);
            DiagnosticBag diagnosticsForThisMethod = DiagnosticBag.GetInstance();

            try
            {
                AsyncMethodBodyDebugInfo asyncDebugInfo = null;
                if ((object)method.AsyncKickoffMethod == null) // is this the MoveNext of an async method?
                {
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints);
                }
                else
                {
                    int asyncCatchHandlerOffset;
                    ImmutableArray <int> asyncYieldPoints;
                    ImmutableArray <int> asyncResumePoints;
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints,
                        out asyncCatchHandlerOffset, out asyncYieldPoints, out asyncResumePoints);
                    asyncDebugInfo = new AsyncMethodBodyDebugInfo(method.AsyncKickoffMethod, asyncCatchHandlerOffset, asyncYieldPoints, asyncResumePoints);
                }

                var localVariables = builder.LocalSlotManager.LocalsInOrder();

                if (localVariables.Length > 0xFFFE)
                {
                    diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
                }

                if (diagnosticsForThisMethod.HasAnyErrors())
                {
                    // we are done here. Since there were errors we should not emit anything.
                    return(null);
                }

                // We will only save the IL builders when running tests.
                if (module.SaveTestData)
                {
                    module.SetMethodTestData(method, builder.GetSnapshot());
                }

                // Only compiler-generated MoveNext methods have iterator scopes.  See if this is one.
                bool hasIteratorScopes =
                    method.Locations.IsEmpty && method.Name == "MoveNext" &&
                    (method.ExplicitInterfaceImplementations.Contains(compilation.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext) as MethodSymbol) ||
                     method.ExplicitInterfaceImplementations.Contains(compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext) as MethodSymbol));

                var iteratorScopes = hasIteratorScopes ? builder.GetIteratorScopes() : ImmutableArray <LocalScope> .Empty;

                var iteratorOrAsyncImplementation = compilationState.GetIteratorOrAsyncImplementationClass(method);
                return(new MethodBody(
                           builder.RealizedIL,
                           builder.MaxStack,
                           method,
                           localVariables,
                           builder.RealizedSequencePoints,
                           debugDocumentProvider,
                           builder.RealizedExceptionHandlers,
                           builder.GetAllScopes(),
                           Microsoft.Cci.CustomDebugInfoKind.CSharpStyle,
                           builder.HasDynamicLocal,
                           namespaceScopes,
                           (object)iteratorOrAsyncImplementation == null ? null : iteratorOrAsyncImplementation.MetadataName,
                           iteratorScopes,
                           asyncMethodDebugInfo: asyncDebugInfo
                           ));
            }
            finally
            {
                // Basic blocks contain poolable builders for IL and sequence points. Free those back
                // to their pools.
                builder.FreeBasicBlocks();

                // Remember diagnostics.
                diagnostics.AddRange(diagnosticsForThisMethod);
                diagnosticsForThisMethod.Free();
            }
        }
コード例 #35
0
        // NOTE: can return null if the method has no body.
        internal static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics)
        {
            ConsList <Imports> unused;

            return(BindMethodBody(method, compilationState, diagnostics, false, out unused));
        }
コード例 #36
0
 public AwaitLoweringRewriterPass2(SyntheticBoundNodeFactory F, TypeCompilationState CompilationState)
 {
     this.F = F;
     this.spillFieldAllocator = new SpillFieldAllocator(F, CompilationState);
 }
コード例 #37
0
        internal static BoundStatement Rewrite(BoundStatement body, MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics)
        {
            var tempSubstitution = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance();

            var       spiller = new SpillSequenceSpiller(method, body.Syntax, compilationState, tempSubstitution, diagnostics);
            BoundNode result  = spiller.Visit(body);

            result = LocalSubstituter.Rewrite(tempSubstitution, result);
            tempSubstitution.Free();
            return((BoundStatement)result);
        }
コード例 #38
0
        // NOTE: can return null if the method has no body.
        internal static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList <Imports> debugImports)
        {
            debugImports = null;

            BoundStatement constructorInitializer = null;
            BoundBlock     body;

            var compilation = method.DeclaringCompilation;

            var sourceMethod = method as SourceMethodSymbol;

            if ((object)sourceMethod != null)
            {
                if (sourceMethod.IsExtern)
                {
                    if (sourceMethod.BlockSyntax == null)
                    {
                        // Generate warnings only if we are not generating ERR_ExternHasBody error
                        GenerateExternalMethodWarnings(sourceMethod, diagnostics);
                    }
                    return(null);
                }
                else if (sourceMethod.IsParameterlessValueTypeConstructor(requireSynthesized: true))
                {
                    // No body for default struct constructor.
                    return(null);
                }

                var blockSyntax = sourceMethod.BlockSyntax;
                if (blockSyntax != null)
                {
                    var factory        = compilation.GetBinderFactory(sourceMethod.SyntaxTree);
                    var inMethodBinder = factory.GetBinder(blockSyntax);
                    var binder         = new ExecutableCodeBinder(blockSyntax, sourceMethod, inMethodBinder);
                    body = binder.BindBlock(blockSyntax, diagnostics);
                    if (generateDebugInfo)
                    {
                        debugImports = binder.ImportsList;
                    }
                    if (inMethodBinder.IsDirectlyInIterator)
                    {
                        foreach (var parameter in method.Parameters)
                        {
                            if (parameter.RefKind != RefKind.None)
                            {
                                diagnostics.Add(ErrorCode.ERR_BadIteratorArgType, parameter.Locations[0]);
                            }
                            else if (parameter.Type.IsUnsafe())
                            {
                                diagnostics.Add(ErrorCode.ERR_UnsafeIteratorArgType, parameter.Locations[0]);
                            }
                        }

                        if (sourceMethod.IsUnsafe && compilation.Options.AllowUnsafe) // Don't cascade
                        {
                            diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, sourceMethod.Locations[0]);
                        }

                        if (sourceMethod.IsVararg)
                        {
                            // error CS1636: __arglist is not allowed in the parameter list of iterators
                            diagnostics.Add(ErrorCode.ERR_VarargsIterator, sourceMethod.Locations[0]);
                        }
                    }
                }
                else // for [if (blockSyntax != null)]
                {
                    var property = sourceMethod.AssociatedSymbol as SourcePropertySymbol;
                    if ((object)property != null && property.IsAutoProperty)
                    {
                        return(MethodBodySynthesizer.ConstructAutoPropertyAccessorBody(sourceMethod));
                    }

                    if (sourceMethod.IsPrimaryCtor)
                    {
                        body = null;
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            else
            {
                //  synthesized methods should return their bound bodies
                body = null;
            }

            // delegates have constructors but not constructor initializers
            if (method.MethodKind == MethodKind.Constructor && !method.ContainingType.IsDelegateType())
            {
                var initializerInvocation = BindConstructorInitializer(method, diagnostics, compilation);

                if (initializerInvocation != null)
                {
                    constructorInitializer = new BoundExpressionStatement(initializerInvocation.Syntax, initializerInvocation)
                    {
                        WasCompilerGenerated = true
                    };
                    Debug.Assert(initializerInvocation.HasAnyErrors || constructorInitializer.IsConstructorInitializer(), "Please keep this bound node in sync with BoundNodeExtensions.IsConstructorInitializer.");
                }
            }

            var statements = ArrayBuilder <BoundStatement> .GetInstance();

            if (constructorInitializer != null)
            {
                statements.Add(constructorInitializer);
            }

            if ((object)sourceMethod != null && sourceMethod.IsPrimaryCtor && (object)((SourceMemberContainerTypeSymbol)sourceMethod.ContainingType).PrimaryCtor == (object)sourceMethod)
            {
                Debug.Assert(method.MethodKind == MethodKind.Constructor && !method.ContainingType.IsDelegateType());
                Debug.Assert(body == null);

                if (sourceMethod.ParameterCount > 0)
                {
                    var factory = new SyntheticBoundNodeFactory(sourceMethod, sourceMethod.SyntaxNode, compilationState, diagnostics);
                    factory.CurrentMethod = sourceMethod;

                    foreach (var parameter in sourceMethod.Parameters)
                    {
                        FieldSymbol field = parameter.PrimaryConstructorParameterBackingField;

                        if ((object)field != null)
                        {
                            statements.Add(factory.Assignment(factory.Field(factory.This(), field),
                                                              factory.Parameter(parameter)));
                        }
                    }
                }
            }

            if (body != null)
            {
                statements.Add(body);
            }

            CSharpSyntaxNode syntax = body != null ? body.Syntax : method.GetNonNullSyntaxNode();

            BoundBlock block;

            if (statements.Count == 1 && statements[0].Kind == ((body == null) ? BoundKind.Block : body.Kind))
            {
                // most common case - we just have a single block for the body.
                block = (BoundBlock)statements[0];
                statements.Free();
            }
            else
            {
                block = new BoundBlock(syntax, default(ImmutableArray <LocalSymbol>), statements.ToImmutableAndFree())
                {
                    WasCompilerGenerated = true
                };
            }

            return(method.MethodKind == MethodKind.Destructor ? MethodBodySynthesizer.ConstructDestructorBody(syntax, method, block) : block);
        }
コード例 #39
0
 private SpillSequenceSpiller(MethodSymbol method, SyntaxNode syntaxNode, TypeCompilationState compilationState, PooledDictionary <LocalSymbol, LocalSymbol> tempSubstitution, DiagnosticBag diagnostics)
 {
     _F = new SyntheticBoundNodeFactory(method, syntaxNode, compilationState, diagnostics);
     _F.CurrentFunction = method;
     _tempSubstitution  = tempSubstitution;
 }
コード例 #40
0
        /// <param name="topLevelMethodOpt">The top-level method that will contain the code</param>
        /// <param name="currentClassOpt">The enclosing class</param>
        /// <param name="node">The syntax node to which generated code should be attributed</param>
        /// <param name="compilationState">The state of compilation of the enclosing type</param>
        /// <param name="diagnostics">A bag where any diagnostics should be output</param>
        public SyntheticBoundNodeFactory(MethodSymbol topLevelMethodOpt, NamedTypeSymbol currentClassOpt, CSharpSyntaxNode node, TypeCompilationState compilationState, DiagnosticBag diagnostics)
        {
            Debug.Assert(node != null);
            Debug.Assert(compilationState != null);
            Debug.Assert(diagnostics != null);

            this.CompilationState = compilationState;
            this.TopLevelMethod   = topLevelMethodOpt;
            this.CurrentClass     = currentClassOpt;
            this.Syntax           = node;
            this.Diagnostics      = diagnostics;
        }
コード例 #41
0
        public IteratorStateMachine(MethodSymbol iteratorMethod, bool isEnumerable, TypeSymbol elementType, TypeCompilationState compilationState)
            : base(GeneratedNames.MakeIteratorOrAsyncDisplayClassName(iteratorMethod.Name, compilationState.GenerateTempNumber()), iteratorMethod)
        {
            this.iteratorMethod = iteratorMethod;
            this.ElementType    = TypeMap.SubstituteType(elementType);

            var interfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance();

            if (isEnumerable)
            {
                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).Construct(ElementType));
                interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_IEnumerable));
            }

            interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerator_T).Construct(ElementType));
            interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_IDisposable));
            interfaces.Add(ContainingAssembly.GetSpecialType(SpecialType.System_Collections_IEnumerator));
            this.interfaces = interfaces.ToImmutableAndFree();

            this.constructor = new IteratorConstructor(this);
        }
コード例 #42
0
 /// <summary>
 /// Create a bound node factory. Note that the use of the factory to get special or well-known members
 /// that do not exist will result in an exception of type <see cref="MissingPredefinedMember"/> being thrown.
 /// </summary>
 /// <param name="topLevelMethod">The top-level method that will contain the code</param>
 /// <param name="node">The syntax node to which generated code should be attributed</param>
 /// <param name="compilationState">The state of compilation of the enclosing type</param>
 /// <param name="diagnostics">A bag where any diagnostics should be output</param>
 public SyntheticBoundNodeFactory(MethodSymbol topLevelMethod, CSharpSyntaxNode node, TypeCompilationState compilationState, DiagnosticBag diagnostics)
     : this(topLevelMethod, topLevelMethod.ContainingType, node, compilationState, diagnostics)
 {
 }
コード例 #43
0
ファイル: LocalRewriter.cs プロジェクト: zyonet/roslyn
        /// <summary>
        /// Lower a block of code by performing local rewritings.
        /// </summary>
        public static BoundStatement Rewrite(
            CSharpCompilation compilation,
            MethodSymbol method,
            int methodOrdinal,
            NamedTypeSymbol containingType,
            BoundStatement statement,
            TypeCompilationState compilationState,
            SynthesizedSubmissionFields previousSubmissionFields,
            bool allowOmissionOfConditionalCalls,
            bool instrumentForDynamicAnalysis,
            ref ImmutableArray <SourceSpan> dynamicAnalysisSpans,
            DebugDocumentProvider debugDocumentProvider,
            DiagnosticBag diagnostics,
            out bool sawLambdas,
            out bool sawLocalFunctions,
            out bool sawAwaitInExceptionHandler)
        {
            Debug.Assert(statement != null);
            Debug.Assert(compilationState != null);

            try
            {
                var factory = new SyntheticBoundNodeFactory(method, statement.Syntax, compilationState, diagnostics);
                DynamicAnalysisInjector dynamicInstrumenter = instrumentForDynamicAnalysis ? DynamicAnalysisInjector.TryCreate(method, statement, factory, diagnostics, debugDocumentProvider, Instrumenter.NoOp) : null;

                // We don’t want IL to differ based upon whether we write the PDB to a file/stream or not.
                // Presence of sequence points in the tree affects final IL, therefore, we always generate them.
                var localRewriter = new LocalRewriter(compilation, method, methodOrdinal, statement, containingType, factory, previousSubmissionFields, allowOmissionOfConditionalCalls, diagnostics,
                                                      dynamicInstrumenter != null ? new DebugInfoInjector(dynamicInstrumenter) : DebugInfoInjector.Singleton);

                statement.CheckLocalsDefined();
                var loweredStatement = (BoundStatement)localRewriter.Visit(statement);
                loweredStatement.CheckLocalsDefined();
                sawLambdas                 = localRewriter._sawLambdas;
                sawLocalFunctions          = localRewriter._sawLocalFunctions;
                sawAwaitInExceptionHandler = localRewriter._sawAwaitInExceptionHandler;

                if (localRewriter._needsSpilling && !loweredStatement.HasErrors)
                {
                    // Move spill sequences to a top-level statement. This handles "lifting" await and the switch expression.
                    var spilledStatement = SpillSequenceSpiller.Rewrite(loweredStatement, method, compilationState, diagnostics);
                    spilledStatement.CheckLocalsDefined();
                    loweredStatement = spilledStatement;
                }

                if (dynamicInstrumenter != null)
                {
                    dynamicAnalysisSpans = dynamicInstrumenter.DynamicAnalysisSpans;
                }
#if DEBUG
                LocalRewritingValidator.Validate(loweredStatement);
#endif
                return(loweredStatement);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                sawLambdas = sawLocalFunctions = sawAwaitInExceptionHandler = false;
                return(new BoundBadStatement(statement.Syntax, ImmutableArray.Create <BoundNode>(statement), hasErrors: true));
            }
        }
コード例 #44
0
        internal static MethodBody GenerateMethodBody(TypeCompilationState compilationState, MethodSymbol method, BoundStatement block, DiagnosticBag diagnostics,
            bool optimize, DebugDocumentProvider debugDocumentProvider, ImmutableArray<NamespaceScope> namespaceScopes)
        {
            // Note: don't call diagnostics.HasAnyErrors() in release; could be expensive if compilation has many warnings.
            Debug.Assert(!diagnostics.HasAnyErrors(), "Running code generator when errors exist might be dangerous; code generator not well hardened");

            bool emitSequencePoints = !namespaceScopes.IsDefault && !method.IsAsync;
            var module = compilationState.ModuleBuilder;
            var compilation = module.Compilation;
            var localSlotManager = module.CreateLocalSlotManager(method);

            ILBuilder builder = new ILBuilder(module, localSlotManager, optimize);
            DiagnosticBag diagnosticsForThisMethod = DiagnosticBag.GetInstance();
            try
            {
                AsyncMethodBodyDebugInfo asyncDebugInfo = null;
                if ((object)method.AsyncKickoffMethod == null) // is this the MoveNext of an async method?
                {
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints);
                }
                else
                {
                    int asyncCatchHandlerOffset;
                    ImmutableArray<int> asyncYieldPoints;
                    ImmutableArray<int> asyncResumePoints;
                    CodeGen.CodeGenerator.Run(
                        method, block, builder, module, diagnosticsForThisMethod, optimize, emitSequencePoints,
                        out asyncCatchHandlerOffset, out asyncYieldPoints, out asyncResumePoints);
                    asyncDebugInfo = new AsyncMethodBodyDebugInfo(method.AsyncKickoffMethod, asyncCatchHandlerOffset, asyncYieldPoints, asyncResumePoints);
                }

                var localVariables = builder.LocalSlotManager.LocalsInOrder();

                if (localVariables.Length > 0xFFFE)
                {
                    diagnosticsForThisMethod.Add(ErrorCode.ERR_TooManyLocals, method.Locations.First());
                }

                if (diagnosticsForThisMethod.HasAnyErrors())
                {
                    // we are done here. Since there were errors we should not emit anything.
                    return null;
                }

                // We will only save the IL builders when running tests.
                if (module.SaveTestData)
                {
                    module.SetMethodTestData(method, builder.GetSnapshot());
                }

                // Only compiler-generated MoveNext methods have iterator scopes.  See if this is one.
                bool hasIteratorScopes =
                    method.Locations.IsEmpty && method.Name == "MoveNext" &&
                    (method.ExplicitInterfaceImplementations.Contains(compilation.GetSpecialTypeMember(SpecialMember.System_Collections_IEnumerator__MoveNext) as MethodSymbol) ||
                     method.ExplicitInterfaceImplementations.Contains(compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_IAsyncStateMachine_MoveNext) as MethodSymbol));

                var iteratorScopes = hasIteratorScopes ? builder.GetIteratorScopes() : ImmutableArray<LocalScope>.Empty;

                var iteratorOrAsyncImplementation = compilationState.GetIteratorOrAsyncImplementationClass(method);
                return new MethodBody(
                    builder.RealizedIL,
                    builder.MaxStack,
                    method,
                    localVariables,
                    builder.RealizedSequencePoints,
                    debugDocumentProvider,
                    builder.RealizedExceptionHandlers,
                    builder.GetAllScopes(),
                    Microsoft.Cci.CustomDebugInfoKind.CSharpStyle,
                    builder.HasDynamicLocal,
                    namespaceScopes,
                    (object)iteratorOrAsyncImplementation == null ? null : iteratorOrAsyncImplementation.MetadataName,
                    iteratorScopes,
                    asyncMethodDebugInfo: asyncDebugInfo
                );
            }
            finally
            {
                // Basic blocks contain poolable builders for IL and sequence points. Free those back
                // to their pools.
                builder.FreeBasicBlocks();

                // Remember diagnostics.
                diagnostics.AddRange(diagnosticsForThisMethod);
                diagnosticsForThisMethod.Free();
            }
        }
コード例 #45
0
 public AwaitLiftingRewriter(MethodSymbol method, CSharpSyntaxNode syntaxNode, TypeCompilationState compilationState, DiagnosticBag diagnostics)
 {
     this.F = new SyntheticBoundNodeFactory(method, syntaxNode, compilationState, diagnostics);
 }
コード例 #46
0
 // NOTE: can return null if the method has no body.
 internal static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics)
 {
     ConsList<Imports> unused;
     return BindMethodBody(method, compilationState, diagnostics, false, out unused);
 }
コード例 #47
0
        private ExpressionLambdaRewriter(TypeCompilationState compilationState, TypeMap typeMap, CSharpSyntaxNode node, DiagnosticBag diagnostics)
        {
            _bound = new SyntheticBoundNodeFactory(null, compilationState.Type, node, compilationState, diagnostics);
            _ignoreAccessibility = compilationState.ModuleBuilderOpt.IgnoreAccessibility;
            _int32Type = _bound.SpecialType(SpecialType.System_Int32);
            _objectType = _bound.SpecialType(SpecialType.System_Object);
            _nullableType = _bound.SpecialType(SpecialType.System_Nullable_T);
            _IEnumerableType = _bound.SpecialType(SpecialType.System_Collections_Generic_IEnumerable_T);

            _typeMap = typeMap;
        }
コード例 #48
0
        internal static MethodSymbol DefineScriptEntryPoint(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuilt, TypeSymbol returnType, bool hasDeclarationErrors, DiagnosticBag diagnostics)
        {
            var scriptEntryPoint = new SynthesizedEntryPointSymbol(compilation.ScriptClass, returnType, diagnostics);
            if (moduleBeingBuilt != null && !hasDeclarationErrors && !diagnostics.HasAnyErrors())
            {
                var compilationState = new TypeCompilationState(compilation.ScriptClass, moduleBeingBuilt);
                var body = scriptEntryPoint.CreateBody();

                var emittedBody = GenerateMethodBody(
                    compilationState,
                    scriptEntryPoint,
                    body,
                    diagnostics,
                    compilation.Options.Optimize,
                    debugDocumentProvider: null,
                    namespaceScopes: default(ImmutableArray<NamespaceScope>));

                moduleBeingBuilt.SetMethodBody(scriptEntryPoint, emittedBody);
                moduleBeingBuilt.AddCompilerGeneratedDefinition(compilation.ScriptClass, scriptEntryPoint);
            }

            return scriptEntryPoint;
        }
コード例 #49
0
 public AwaitLiftingRewriter(MethodSymbol method, CSharpSyntaxNode syntaxNode, TypeCompilationState compilationState, DiagnosticBag diagnostics)
 {
     this.F = new SyntheticBoundNodeFactory(method, syntaxNode, compilationState, diagnostics);
 }
コード例 #50
0
        internal SynthesizedClosureMethod(
            NamedTypeSymbol containingType,
            ImmutableArray <SynthesizedClosureEnvironment> structEnvironments,
            ClosureKind closureKind,
            MethodSymbol topLevelMethod,
            DebugId topLevelMethodId,
            MethodSymbol originalMethod,
            SyntaxReference blockSyntax,
            DebugId lambdaId,
            TypeCompilationState compilationState)
            : base(containingType,
                   originalMethod,
                   blockSyntax,
                   originalMethod.DeclaringSyntaxReferences[0].GetLocation(),
                   originalMethod is LocalFunctionSymbol
                    ? MakeName(topLevelMethod.Name, originalMethod.Name, topLevelMethodId, closureKind, lambdaId)
                    : MakeName(topLevelMethod.Name, topLevelMethodId, closureKind, lambdaId),
                   MakeDeclarationModifiers(closureKind, originalMethod))
        {
            Debug.Assert(containingType.DeclaringCompilation is not null);

            TopLevelMethod = topLevelMethod;
            ClosureKind    = closureKind;
            LambdaId       = lambdaId;

            TypeMap typeMap;
            ImmutableArray <TypeParameterSymbol> typeParameters;

            var lambdaFrame = ContainingType as SynthesizedClosureEnvironment;

            switch (closureKind)
            {
            case ClosureKind.Singleton:   // all type parameters on method (except the top level method's)
            case ClosureKind.General:     // only lambda's type parameters on method (rest on class)
                RoslynDebug.Assert(!(lambdaFrame is null));
                typeMap = lambdaFrame.TypeMap.WithConcatAlphaRename(
                    originalMethod,
                    this,
                    out typeParameters,
                    out _,
                    lambdaFrame.OriginalContainingMethodOpt);
                break;

            case ClosureKind.ThisOnly:     // all type parameters on method
            case ClosureKind.Static:
                RoslynDebug.Assert(lambdaFrame is null);
                typeMap = TypeMap.Empty.WithConcatAlphaRename(
                    originalMethod,
                    this,
                    out typeParameters,
                    out _,
                    stopAt: null);
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(closureKind);
            }

            if (!structEnvironments.IsDefaultOrEmpty && typeParameters.Length != 0)
            {
                var constructedStructClosures = ArrayBuilder <NamedTypeSymbol> .GetInstance();

                foreach (var env in structEnvironments)
                {
                    NamedTypeSymbol constructed;
                    if (env.Arity == 0)
                    {
                        constructed = env;
                    }
                    else
                    {
                        var originals = env.ConstructedFromTypeParameters;
                        var newArgs   = typeMap.SubstituteTypeParameters(originals);
                        constructed = env.Construct(newArgs);
                    }
                    constructedStructClosures.Add(constructed);
                }
                _structEnvironments = constructedStructClosures.ToImmutableAndFree();
            }
            else
            {
                _structEnvironments = ImmutableArray <NamedTypeSymbol> .CastUp(structEnvironments);
            }

            AssignTypeMapAndTypeParameters(typeMap, typeParameters);
            EnsureAttributesExist(compilationState);

            // static local functions should be emitted as static.
            Debug.Assert(!(originalMethod is LocalFunctionSymbol) || !originalMethod.IsStatic || IsStatic);
        }
コード例 #51
0
 private AwaitExpressionSpiller(MethodSymbol method, SyntaxNode syntaxNode, TypeCompilationState compilationState, PooledDictionary <LocalSymbol, LocalSymbol> tempSubstitution, DiagnosticBag diagnostics)
 {
     _F = new SyntheticBoundNodeFactory(method, syntaxNode, compilationState, diagnostics);
     _tempSubstitution = tempSubstitution;
 }
コード例 #52
0
 internal static BoundStatement Rewrite(BoundStatement body, MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics)
 {
     return new AwaitLiftingRewriter(method, body.Syntax, compilationState, diagnostics).Rewrite(body);
 }
コード例 #53
0
        internal static BoundStatement Rewrite(BoundStatement body, MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics)
        {
            var tempSubstitution = PooledDictionary <LocalSymbol, LocalSymbol> .GetInstance();

            var spiller = new AwaitExpressionSpiller(method, body.Syntax, compilationState, tempSubstitution, diagnostics);
            var result  = (BoundStatement)spiller.Visit(body);

            tempSubstitution.Free();
            return(result);
        }
コード例 #54
0
 internal static BoundNode RewriteLambda(BoundLambda node, TypeCompilationState compilationState, TypeMap typeMap, DiagnosticBag diagnostics)
 {
     try
     {
         var r = new ExpressionLambdaRewriter(compilationState, typeMap, node.Syntax, diagnostics);
         var result = r.VisitLambdaInternal(node);
         if (node.Type != result.Type)
         {
             diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, node.Syntax.Location, r.ExpressionType, "Lambda");
         }
         return result;
     }
     catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
     {
         diagnostics.Add(ex.Diagnostic);
         return node;
     }
 }
コード例 #55
0
        internal SynthesizedLambdaMethod(NamedTypeSymbol containingType, MethodSymbol topLevelMethod, BoundLambda node, bool isStatic, TypeCompilationState compilationState)
            : base(containingType,
                   node.Symbol,
                   null,
                   node.SyntaxTree.GetReference(node.Body.Syntax),
                   node.Syntax.GetLocation(),
                   GeneratedNames.MakeLambdaMethodName(topLevelMethod.Name, compilationState.GenerateTempNumber()),
                   (containingType is LambdaFrame ? DeclarationModifiers.Internal : DeclarationModifiers.Private)
                   | (isStatic ? DeclarationModifiers.Static : 0)
                   | (node.Symbol.IsAsync ? DeclarationModifiers.Async : 0))
        {
            TypeMap typeMap;
            ImmutableArray <TypeParameterSymbol> typeParameters;
            LambdaFrame lambdaFrame;

            if (!topLevelMethod.IsGenericMethod)
            {
                typeMap        = TypeMap.Empty;
                typeParameters = ImmutableArray <TypeParameterSymbol> .Empty;
            }
            else if ((object)(lambdaFrame = this.ContainingType as LambdaFrame) != null)
            {
                typeMap        = lambdaFrame.TypeMap;
                typeParameters = ImmutableArray <TypeParameterSymbol> .Empty;
            }
            else
            {
                typeMap = TypeMap.Empty.WithAlphaRename(topLevelMethod, this, out typeParameters);
            }

            AssignTypeMapAndTypeParameters(typeMap, typeParameters);
        }
コード例 #56
0
 internal LambdaFrameLocalSymbol(MethodSymbol containingMethod, TypeSymbol type, TypeCompilationState compilationState)
     : base(containingMethod, type, GeneratedNames.MakeLambdaDisplayClassLocalName(compilationState.GenerateTempNumber()), declarationKind: LocalDeclarationKind.CompilerGeneratedLambdaDisplayClassLocal)
 {
 }
コード例 #57
0
ファイル: LambdaFrame.cs プロジェクト: ARLM-Attic/cs-native
 internal LambdaFrame(MethodSymbol topLevelMethod, TypeCompilationState compilationState)
     : base(GeneratedNames.MakeLambdaDisplayClassName(compilationState.GenerateTempNumber()), topLevelMethod)
 {
     this.topLevelMethod = topLevelMethod;
     this.constructor    = new LambdaFrameConstructor(this);
 }