| File: Lowering\LocalRewriter\LoweredDynamicOperation.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp { /// <summary> /// The dynamic operation factories below return this struct so that the caller /// have the option of separating the call-site initialization from its invocation. /// /// Most callers just call <see cref="ToExpression"/> to get the combo but some (object and array initializers) /// hoist all call-site initialization code and emit multiple invocations of the same site. /// </summary> internal readonly struct LoweredDynamicOperation { private readonly SyntheticBoundNodeFactory? _factory; private readonly TypeSymbol _resultType; private readonly ImmutableArray<LocalSymbol> _temps; public readonly BoundExpression? SiteInitialization; public readonly BoundExpression SiteInvocation; public LoweredDynamicOperation(SyntheticBoundNodeFactory? factory, BoundExpression? siteInitialization, BoundExpression siteInvocation, TypeSymbol resultType, ImmutableArray<LocalSymbol> temps) { _factory = factory; _resultType = resultType; _temps = temps; this.SiteInitialization = siteInitialization; this.SiteInvocation = siteInvocation; } public static LoweredDynamicOperation Bad( BoundExpression? loweredReceiver, ImmutableArray<BoundExpression> loweredArguments, BoundExpression? loweredRight, TypeSymbol resultType) { var children = ArrayBuilder<BoundExpression>.GetInstance(); children.AddIfNotNull(loweredReceiver); children.AddRange(loweredArguments); children.AddIfNotNull(loweredRight); return LoweredDynamicOperation.Bad(resultType, children.ToImmutableAndFree()); } public static LoweredDynamicOperation Bad(TypeSymbol resultType, ImmutableArray<BoundExpression> children) { Debug.Assert(children.Length > 0); var bad = new BoundBadExpression(children[0].Syntax, LookupResultKind.Empty, ImmutableArray<Symbol?>.Empty, children, resultType); return new LoweredDynamicOperation(null, null, bad, resultType, default(ImmutableArray<LocalSymbol>)); } public BoundExpression ToExpression() { if (_factory == null) { Debug.Assert(SiteInitialization == null && SiteInvocation is BoundBadExpression && _temps.IsDefaultOrEmpty); return SiteInvocation; } // TODO (tomat): we might be able to use SiteInvocation.Type instead of resultType once we stop using GetLoweredType Debug.Assert(SiteInitialization is { }); if (_temps.IsDefaultOrEmpty) { return _factory.Sequence(new[] { SiteInitialization }, SiteInvocation, _resultType); } else { return new BoundSequence(_factory.Syntax, _temps, ImmutableArray.Create(SiteInitialization), SiteInvocation, _resultType) { WasCompilerGenerated = true }; } } } }