|
// 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.PooledObjects;
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed partial class BoundFieldAccess
{
public BoundFieldAccess(
SyntaxNode syntax,
BoundExpression? receiver,
FieldSymbol fieldSymbol,
ConstantValue? constantValueOpt,
bool hasErrors = false)
: this(syntax, receiver, fieldSymbol, constantValueOpt, LookupResultKind.Viable, fieldSymbol.Type, hasErrors)
{
}
public BoundFieldAccess(
SyntaxNode syntax,
BoundExpression? receiver,
FieldSymbol fieldSymbol,
ConstantValue? constantValueOpt,
LookupResultKind resultKind,
TypeSymbol type,
bool hasErrors = false)
: this(syntax, receiver, fieldSymbol, constantValueOpt, resultKind, NeedsByValueFieldAccess(receiver, fieldSymbol), isDeclaration: false, type: type, hasErrors: hasErrors)
{
}
public BoundFieldAccess(
SyntaxNode syntax,
BoundExpression? receiver,
FieldSymbol fieldSymbol,
ConstantValue? constantValueOpt,
LookupResultKind resultKind,
bool isDeclaration,
TypeSymbol type,
bool hasErrors = false)
: this(syntax, receiver, fieldSymbol, constantValueOpt, resultKind, NeedsByValueFieldAccess(receiver, fieldSymbol), isDeclaration: isDeclaration, type: type, hasErrors: hasErrors)
{
}
public BoundFieldAccess Update(
BoundExpression? receiver,
FieldSymbol fieldSymbol,
ConstantValue? constantValueOpt,
LookupResultKind resultKind,
TypeSymbol typeSymbol)
{
return this.Update(receiver, fieldSymbol, constantValueOpt, resultKind, this.IsByValue, this.IsDeclaration, typeSymbol);
}
private static bool NeedsByValueFieldAccess(BoundExpression? receiver, FieldSymbol fieldSymbol)
{
if (fieldSymbol.IsStatic ||
!fieldSymbol.ContainingType.IsValueType ||
fieldSymbol.RefKind != RefKind.None ||
receiver == null) // receiver may be null in error cases
{
return false;
}
switch (receiver.Kind)
{
case BoundKind.FieldAccess:
return ((BoundFieldAccess)receiver).IsByValue;
case BoundKind.Local:
var localSymbol = ((BoundLocal)receiver).LocalSymbol;
return !(localSymbol.IsWritableVariable || localSymbol.IsRef);
default:
return false;
}
}
}
internal partial class BoundCall
{
public BoundCall(
SyntaxNode syntax,
BoundExpression? receiverOpt,
ThreeState initialBindingReceiverIsSubjectToCloning,
MethodSymbol method,
ImmutableArray<BoundExpression> arguments,
ImmutableArray<string?> argumentNamesOpt,
ImmutableArray<RefKind> argumentRefKindsOpt,
bool isDelegateCall,
bool expanded,
bool invokedAsExtensionMethod,
ImmutableArray<int> argsToParamsOpt,
BitVector defaultArguments,
LookupResultKind resultKind,
TypeSymbol type,
bool hasErrors = false) :
this(syntax, receiverOpt, initialBindingReceiverIsSubjectToCloning, method, arguments, argumentNamesOpt, argumentRefKindsOpt, isDelegateCall, expanded, invokedAsExtensionMethod, argsToParamsOpt, defaultArguments, resultKind, originalMethodsOpt: default, type: type, hasErrors: hasErrors)
{
}
public BoundCall Update(BoundExpression? receiverOpt,
ThreeState initialBindingReceiverIsSubjectToCloning,
MethodSymbol method,
ImmutableArray<BoundExpression> arguments,
ImmutableArray<string?> argumentNamesOpt,
ImmutableArray<RefKind> argumentRefKindsOpt,
bool isDelegateCall,
bool expanded,
bool invokedAsExtensionMethod,
ImmutableArray<int> argsToParamsOpt,
BitVector defaultArguments,
LookupResultKind resultKind,
TypeSymbol type)
=> Update(receiverOpt, initialBindingReceiverIsSubjectToCloning, method, arguments, argumentNamesOpt, argumentRefKindsOpt, isDelegateCall, expanded, invokedAsExtensionMethod, argsToParamsOpt, defaultArguments, resultKind, this.OriginalMethodsOpt, type);
public static BoundCall ErrorCall(
SyntaxNode node,
BoundExpression receiverOpt,
MethodSymbol method,
ImmutableArray<BoundExpression> arguments,
ImmutableArray<string?> namedArguments,
ImmutableArray<RefKind> refKinds,
bool isDelegateCall,
bool invokedAsExtensionMethod,
ImmutableArray<MethodSymbol> originalMethods,
LookupResultKind resultKind,
Binder binder)
{
if (!originalMethods.IsEmpty)
resultKind = resultKind.WorseResultKind(LookupResultKind.OverloadResolutionFailure);
Debug.Assert(arguments.IsDefaultOrEmpty || (object)receiverOpt != (object)arguments[0]);
return new BoundCall(
syntax: node,
receiverOpt: binder.BindToTypeForErrorRecovery(receiverOpt),
initialBindingReceiverIsSubjectToCloning: ThreeState.False,
method: method,
arguments: arguments.SelectAsArray((e, binder) => binder.BindToTypeForErrorRecovery(e), binder),
argumentNamesOpt: namedArguments,
argumentRefKindsOpt: refKinds,
isDelegateCall: isDelegateCall,
expanded: false,
invokedAsExtensionMethod: invokedAsExtensionMethod,
argsToParamsOpt: default(ImmutableArray<int>),
defaultArguments: default(BitVector),
resultKind: resultKind,
originalMethodsOpt: originalMethods,
type: method.ReturnType,
hasErrors: true);
}
public BoundCall Update(ImmutableArray<BoundExpression> arguments)
{
return this.Update(ReceiverOpt, InitialBindingReceiverIsSubjectToCloning, Method, arguments, ArgumentNamesOpt, ArgumentRefKindsOpt, IsDelegateCall, Expanded, InvokedAsExtensionMethod, ArgsToParamsOpt, DefaultArguments, ResultKind, OriginalMethodsOpt, Type);
}
public BoundCall Update(BoundExpression? receiverOpt, ThreeState initialBindingReceiverIsSubjectToCloning, MethodSymbol method, ImmutableArray<BoundExpression> arguments)
{
return this.Update(receiverOpt, initialBindingReceiverIsSubjectToCloning, method, arguments, ArgumentNamesOpt, ArgumentRefKindsOpt, IsDelegateCall, Expanded, InvokedAsExtensionMethod, ArgsToParamsOpt, DefaultArguments, ResultKind, OriginalMethodsOpt, Type);
}
public static BoundCall Synthesized(SyntaxNode syntax, BoundExpression? receiverOpt, ThreeState initialBindingReceiverIsSubjectToCloning, MethodSymbol method)
{
return Synthesized(syntax, receiverOpt, initialBindingReceiverIsSubjectToCloning: initialBindingReceiverIsSubjectToCloning, method, ImmutableArray<BoundExpression>.Empty);
}
public static BoundCall Synthesized(SyntaxNode syntax, BoundExpression? receiverOpt, ThreeState initialBindingReceiverIsSubjectToCloning, MethodSymbol method, BoundExpression arg0)
{
return Synthesized(syntax, receiverOpt, initialBindingReceiverIsSubjectToCloning: initialBindingReceiverIsSubjectToCloning, method, ImmutableArray.Create(arg0));
}
public static BoundCall Synthesized(SyntaxNode syntax, BoundExpression? receiverOpt, ThreeState initialBindingReceiverIsSubjectToCloning, MethodSymbol method, BoundExpression arg0, BoundExpression arg1)
{
return Synthesized(syntax, receiverOpt, initialBindingReceiverIsSubjectToCloning: initialBindingReceiverIsSubjectToCloning, method, ImmutableArray.Create(arg0, arg1));
}
public static BoundCall Synthesized(SyntaxNode syntax, BoundExpression? receiverOpt, ThreeState initialBindingReceiverIsSubjectToCloning, MethodSymbol method, ImmutableArray<BoundExpression> arguments, ImmutableArray<RefKind> argumentRefKindsOpt = default)
{
argumentRefKindsOpt = argumentRefKindsOpt.IsDefault ? getArgumentRefKinds(method) : argumentRefKindsOpt;
#if DEBUG
for (int i = 0; i < arguments.Length; i++)
{
if (i < method.ParameterCount)
{
var parameterRefKind = method.ParameterRefKinds.IsDefault ? RefKind.None : method.ParameterRefKinds[i];
var argumentRefKind = argumentRefKindsOpt.IsDefault ? RefKind.None : argumentRefKindsOpt[i];
Debug.Assert(argumentRefKind is RefKind.None or RefKind.Ref or RefKind.In or RefKind.Out or RefKindExtensions.StrictIn &&
(argumentRefKind == parameterRefKind ||
parameterRefKind switch
{
RefKind.In => argumentRefKind == RefKindExtensions.StrictIn,
RefKind.RefReadOnlyParameter => argumentRefKind is RefKind.In or RefKindExtensions.StrictIn,
_ => false,
}),
$"argument ref kind {argumentRefKind} should be compatible with the corresponding parameter ref kind {parameterRefKind}");
}
else
{
Debug.Assert(method is ErrorMethodSymbol || arguments[i].Kind == BoundKind.ArgListOperator);
}
}
#endif
return new BoundCall(syntax,
receiverOpt,
initialBindingReceiverIsSubjectToCloning: initialBindingReceiverIsSubjectToCloning,
method: method,
arguments: arguments,
argumentNamesOpt: default(ImmutableArray<string?>),
argumentRefKindsOpt: argumentRefKindsOpt,
isDelegateCall: false,
expanded: false,
invokedAsExtensionMethod: false,
argsToParamsOpt: default(ImmutableArray<int>),
defaultArguments: default(BitVector),
resultKind: LookupResultKind.Viable,
originalMethodsOpt: default,
type: method.ReturnType,
hasErrors: method.OriginalDefinition is ErrorMethodSymbol
)
{ WasCompilerGenerated = true };
static ImmutableArray<RefKind> getArgumentRefKinds(MethodSymbol method)
{
var result = method.ParameterRefKinds;
if (!result.IsDefaultOrEmpty && result.Contains(RefKind.RefReadOnlyParameter))
{
var builder = ArrayBuilder<RefKind>.GetInstance(result.Length);
foreach (var refKind in result)
{
builder.Add(refKind == RefKind.RefReadOnlyParameter ? RefKind.In : refKind);
}
return builder.ToImmutableAndFree();
}
return result;
}
}
}
internal sealed partial class BoundObjectCreationExpression
{
public BoundObjectCreationExpression(SyntaxNode syntax, MethodSymbol constructor, params BoundExpression[] arguments)
: this(syntax, constructor, ImmutableArray.Create<BoundExpression>(arguments), default(ImmutableArray<string?>), default(ImmutableArray<RefKind>), false, default(ImmutableArray<int>), default(BitVector), null, null, constructor.ContainingType)
{
}
public BoundObjectCreationExpression(SyntaxNode syntax, MethodSymbol constructor, ImmutableArray<BoundExpression> arguments)
: this(syntax, constructor, arguments, default(ImmutableArray<string?>), default(ImmutableArray<RefKind>), false, default(ImmutableArray<int>), default(BitVector), null, null, constructor.ContainingType)
{
}
}
internal partial class BoundIndexerAccess
{
public static BoundIndexerAccess ErrorAccess(
SyntaxNode node,
BoundExpression receiverOpt,
PropertySymbol indexer,
ImmutableArray<BoundExpression> arguments,
ImmutableArray<string?> namedArguments,
ImmutableArray<RefKind> refKinds,
ImmutableArray<PropertySymbol> originalIndexers)
{
return new BoundIndexerAccess(
node,
receiverOpt,
initialBindingReceiverIsSubjectToCloning: ThreeState.False,
indexer,
arguments,
namedArguments,
refKinds,
expanded: false,
accessorKind: AccessorKind.Unknown,
argsToParamsOpt: default(ImmutableArray<int>),
defaultArguments: default(BitVector),
originalIndexersOpt: originalIndexers,
type: indexer.Type,
hasErrors: true);
}
public BoundIndexerAccess(
SyntaxNode syntax,
BoundExpression? receiverOpt,
ThreeState initialBindingReceiverIsSubjectToCloning,
PropertySymbol indexer,
ImmutableArray<BoundExpression> arguments,
ImmutableArray<string?> argumentNamesOpt,
ImmutableArray<RefKind> argumentRefKindsOpt,
bool expanded,
AccessorKind accessorKind,
ImmutableArray<int> argsToParamsOpt,
BitVector defaultArguments,
TypeSymbol type,
bool hasErrors = false) :
this(syntax, receiverOpt, initialBindingReceiverIsSubjectToCloning, indexer, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, accessorKind, argsToParamsOpt, defaultArguments, originalIndexersOpt: default, type, hasErrors)
{ }
public BoundIndexerAccess Update(BoundExpression? receiverOpt,
ThreeState initialBindingReceiverIsSubjectToCloning,
PropertySymbol indexer,
ImmutableArray<BoundExpression> arguments,
ImmutableArray<string?> argumentNamesOpt,
ImmutableArray<RefKind> argumentRefKindsOpt,
bool expanded,
AccessorKind accessorKind,
ImmutableArray<int> argsToParamsOpt,
BitVector defaultArguments,
TypeSymbol type)
=> Update(receiverOpt, initialBindingReceiverIsSubjectToCloning, indexer, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, accessorKind, argsToParamsOpt, defaultArguments, this.OriginalIndexersOpt, type);
}
internal sealed partial class BoundConversion
{
/// <remarks>
/// This method is intended for passes other than the LocalRewriter.
/// Use MakeConversion helper method in the LocalRewriter instead,
/// it generates a synthesized conversion in its lowered form.
/// </remarks>
public static BoundConversion SynthesizedNonUserDefined(SyntaxNode syntax, BoundExpression operand, Conversion conversion, TypeSymbol type, ConstantValue? constantValueOpt = null)
{
return new BoundConversion(
syntax,
operand,
conversion,
isBaseConversion: false,
@checked: false,
explicitCastInCode: false,
conversionGroupOpt: null,
constantValueOpt: constantValueOpt,
originalUserDefinedConversionsOpt: default,
type: type)
{ WasCompilerGenerated = true };
}
/// <remarks>
/// NOTE: This method is intended for passes other than the LocalRewriter.
/// NOTE: Use MakeConversion helper method in the LocalRewriter instead,
/// NOTE: it generates a synthesized conversion in its lowered form.
/// </remarks>
public static BoundConversion Synthesized(
SyntaxNode syntax,
BoundExpression operand,
Conversion conversion,
bool @checked,
bool explicitCastInCode,
ConversionGroup? conversionGroupOpt,
ConstantValue? constantValueOpt,
TypeSymbol type,
bool hasErrors = false)
{
return new BoundConversion(
syntax,
operand,
conversion,
@checked,
explicitCastInCode: explicitCastInCode,
conversionGroupOpt,
constantValueOpt,
type,
hasErrors || !conversion.IsValid)
{
WasCompilerGenerated = true
};
}
public BoundConversion(
SyntaxNode syntax,
BoundExpression operand,
Conversion conversion,
bool @checked,
bool explicitCastInCode,
ConversionGroup? conversionGroupOpt,
ConstantValue? constantValueOpt,
TypeSymbol type,
bool hasErrors = false)
: this(
syntax,
operand,
conversion,
isBaseConversion: false,
@checked: @checked,
explicitCastInCode: explicitCastInCode,
constantValueOpt: constantValueOpt,
conversionGroupOpt,
conversion.OriginalUserDefinedConversions,
type: type,
hasErrors: hasErrors || !conversion.IsValid)
{ }
public BoundConversion(
SyntaxNode syntax,
BoundExpression operand,
Conversion conversion,
bool isBaseConversion,
bool @checked,
bool explicitCastInCode,
ConstantValue? constantValueOpt,
ConversionGroup? conversionGroupOpt,
TypeSymbol type,
bool hasErrors = false) :
this(syntax, operand, conversion, isBaseConversion, @checked, explicitCastInCode, constantValueOpt, conversionGroupOpt, originalUserDefinedConversionsOpt: default, type, hasErrors)
{
}
public BoundConversion Update(BoundExpression operand,
Conversion conversion,
bool isBaseConversion,
bool @checked,
bool explicitCastInCode,
ConstantValue? constantValueOpt,
ConversionGroup? conversionGroupOpt,
TypeSymbol type)
=> Update(operand, conversion, isBaseConversion, @checked, explicitCastInCode, constantValueOpt, conversionGroupOpt, this.OriginalUserDefinedConversionsOpt, type);
}
internal sealed partial class BoundBinaryOperator
{
public BoundBinaryOperator(
SyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression left,
BoundExpression right,
ConstantValue? constantValueOpt,
MethodSymbol? methodOpt,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
ImmutableArray<MethodSymbol> originalUserDefinedOperatorsOpt,
TypeSymbol type,
bool hasErrors = false)
: this(
syntax,
operatorKind,
UncommonData.CreateIfNeeded(constantValueOpt, methodOpt, constrainedToTypeOpt, originalUserDefinedOperatorsOpt),
resultKind,
left,
right,
type,
hasErrors)
{
}
public BoundBinaryOperator(
SyntaxNode syntax,
BinaryOperatorKind operatorKind,
ConstantValue? constantValueOpt,
MethodSymbol? methodOpt,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
BoundExpression left,
BoundExpression right,
TypeSymbol type,
bool hasErrors = false) :
this(syntax, operatorKind, UncommonData.CreateIfNeeded(constantValueOpt, methodOpt, constrainedToTypeOpt, originalUserDefinedOperatorsOpt: default), resultKind, left, right, type, hasErrors)
{
}
public BoundBinaryOperator Update(BinaryOperatorKind operatorKind,
ConstantValue? constantValueOpt,
MethodSymbol? methodOpt,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
BoundExpression left,
BoundExpression right,
TypeSymbol type)
{
var uncommonData = UncommonData.CreateIfNeeded(constantValueOpt, methodOpt, constrainedToTypeOpt, OriginalUserDefinedOperatorsOpt);
return Update(operatorKind, uncommonData, resultKind, left, right, type);
}
public BoundBinaryOperator Update(UncommonData uncommonData)
{
return Update(OperatorKind, uncommonData, ResultKind, Left, Right, Type);
}
}
internal sealed partial class BoundUserDefinedConditionalLogicalOperator
{
public BoundUserDefinedConditionalLogicalOperator(
SyntaxNode syntax,
BinaryOperatorKind operatorKind,
BoundExpression left,
BoundExpression right,
MethodSymbol logicalOperator,
MethodSymbol trueOperator,
MethodSymbol falseOperator,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
ImmutableArray<MethodSymbol> originalUserDefinedOperatorsOpt,
TypeSymbol type,
bool hasErrors = false)
: this(
syntax,
operatorKind,
logicalOperator,
trueOperator,
falseOperator,
constrainedToTypeOpt,
resultKind,
originalUserDefinedOperatorsOpt,
left,
right,
type,
hasErrors)
{
Debug.Assert(operatorKind.IsUserDefined() && operatorKind.IsLogical());
}
public BoundUserDefinedConditionalLogicalOperator Update(BinaryOperatorKind operatorKind,
MethodSymbol logicalOperator,
MethodSymbol trueOperator,
MethodSymbol falseOperator,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
BoundExpression left,
BoundExpression right,
TypeSymbol type)
=> Update(operatorKind, logicalOperator, trueOperator, falseOperator, constrainedToTypeOpt, resultKind, this.OriginalUserDefinedOperatorsOpt, left, right, type);
}
internal sealed partial class BoundParameter
{
public BoundParameter(SyntaxNode syntax, ParameterSymbol parameterSymbol, bool hasErrors = false)
: this(syntax, parameterSymbol, parameterSymbol.Type, hasErrors)
{
}
public BoundParameter(SyntaxNode syntax, ParameterSymbol parameterSymbol)
: this(syntax, parameterSymbol, parameterSymbol.Type)
{
}
}
internal sealed partial class BoundTypeExpression
{
public BoundTypeExpression(SyntaxNode syntax, AliasSymbol? aliasOpt, BoundTypeExpression? boundContainingTypeOpt, ImmutableArray<BoundExpression> boundDimensionsOpt, TypeWithAnnotations typeWithAnnotations, bool hasErrors = false)
: this(syntax, aliasOpt, boundContainingTypeOpt, boundDimensionsOpt, typeWithAnnotations, typeWithAnnotations.Type, hasErrors)
{
Debug.Assert((object)typeWithAnnotations.Type != null, "Field 'type' cannot be null");
}
public BoundTypeExpression(SyntaxNode syntax, AliasSymbol? aliasOpt, BoundTypeExpression? boundContainingTypeOpt, TypeWithAnnotations typeWithAnnotations, bool hasErrors = false)
: this(syntax, aliasOpt, boundContainingTypeOpt, ImmutableArray<BoundExpression>.Empty, typeWithAnnotations, hasErrors)
{
}
public BoundTypeExpression(SyntaxNode syntax, AliasSymbol? aliasOpt, TypeWithAnnotations typeWithAnnotations, bool hasErrors = false)
: this(syntax, aliasOpt, null, typeWithAnnotations, hasErrors)
{
}
public BoundTypeExpression(SyntaxNode syntax, AliasSymbol? aliasOpt, TypeSymbol type, bool hasErrors = false)
: this(syntax, aliasOpt, null, TypeWithAnnotations.Create(type), hasErrors)
{
}
public BoundTypeExpression(SyntaxNode syntax, AliasSymbol? aliasOpt, ImmutableArray<BoundExpression> dimensionsOpt, TypeWithAnnotations typeWithAnnotations, bool hasErrors = false)
: this(syntax, aliasOpt, null, dimensionsOpt, typeWithAnnotations, hasErrors)
{
}
}
internal sealed partial class BoundNamespaceExpression
{
public BoundNamespaceExpression(SyntaxNode syntax, NamespaceSymbol namespaceSymbol, bool hasErrors = false)
: this(syntax, namespaceSymbol, null, hasErrors)
{
}
public BoundNamespaceExpression(SyntaxNode syntax, NamespaceSymbol namespaceSymbol)
: this(syntax, namespaceSymbol, null)
{
}
public BoundNamespaceExpression Update(NamespaceSymbol namespaceSymbol)
{
return Update(namespaceSymbol, this.AliasOpt);
}
}
internal sealed partial class BoundAssignmentOperator
{
public BoundAssignmentOperator(SyntaxNode syntax, BoundExpression left, BoundExpression right,
TypeSymbol type, bool isRef = false, bool hasErrors = false)
: this(syntax, left, right, isRef, type, hasErrors)
{
}
}
internal sealed partial class BoundBadExpression
{
public BoundBadExpression(SyntaxNode syntax, LookupResultKind resultKind, ImmutableArray<Symbol?> symbols, ImmutableArray<BoundExpression> childBoundNodes, TypeSymbol type)
: this(syntax, resultKind, symbols, childBoundNodes, type, true)
{
Debug.Assert((object)type != null);
}
}
internal partial class BoundStatementList
{
public static BoundStatementList Synthesized(SyntaxNode syntax, params BoundStatement[] statements)
{
return Synthesized(syntax, false, statements.AsImmutableOrNull());
}
public static BoundStatementList Synthesized(SyntaxNode syntax, bool hasErrors, params BoundStatement[] statements)
{
return Synthesized(syntax, hasErrors, statements.AsImmutableOrNull());
}
public static BoundStatementList Synthesized(SyntaxNode syntax, ImmutableArray<BoundStatement> statements)
{
return Synthesized(syntax, false, statements);
}
public static BoundStatementList Synthesized(SyntaxNode syntax, bool hasErrors, ImmutableArray<BoundStatement> statements)
{
return new BoundStatementList(syntax, statements, hasErrors) { WasCompilerGenerated = true };
}
}
internal sealed partial class BoundReturnStatement
{
public static BoundReturnStatement Synthesized(SyntaxNode syntax, RefKind refKind, BoundExpression expression, bool hasErrors = false)
{
return new BoundReturnStatement(syntax, refKind, expression, hasErrors) { WasCompilerGenerated = true };
}
}
internal sealed partial class BoundYieldBreakStatement
{
public static BoundYieldBreakStatement Synthesized(SyntaxNode syntax, bool hasErrors = false)
{
return new BoundYieldBreakStatement(syntax, hasErrors) { WasCompilerGenerated = true };
}
}
internal sealed partial class BoundGotoStatement
{
public BoundGotoStatement(SyntaxNode syntax, LabelSymbol label, bool hasErrors = false)
: this(syntax, label, caseExpressionOpt: null, labelExpressionOpt: null, hasErrors: hasErrors)
{
}
}
internal partial class BoundBlock
{
public BoundBlock(SyntaxNode syntax, ImmutableArray<LocalSymbol> locals, ImmutableArray<BoundStatement> statements, bool hasErrors = false)
: this(syntax, locals, ImmutableArray<LocalFunctionSymbol>.Empty, hasUnsafeModifier: false, instrumentation: null, statements, hasErrors)
{
}
public static BoundBlock SynthesizedNoLocals(SyntaxNode syntax, BoundStatement statement)
{
return new BoundBlock(syntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray.Create(statement))
{ WasCompilerGenerated = true };
}
public static BoundBlock SynthesizedNoLocals(SyntaxNode syntax, ImmutableArray<BoundStatement> statements)
{
return new BoundBlock(syntax, ImmutableArray<LocalSymbol>.Empty, statements) { WasCompilerGenerated = true };
}
public static BoundBlock SynthesizedNoLocals(SyntaxNode syntax, params BoundStatement[] statements)
{
return new BoundBlock(syntax, ImmutableArray<LocalSymbol>.Empty, statements.AsImmutableOrNull()) { WasCompilerGenerated = true };
}
}
internal sealed partial class BoundDefaultExpression
{
public BoundDefaultExpression(SyntaxNode syntax, TypeSymbol type, bool hasErrors = false)
: this(syntax, targetType: null, type.GetDefaultValue(), type, hasErrors)
{
}
}
internal partial class BoundTryStatement
{
public BoundTryStatement(SyntaxNode syntax, BoundBlock tryBlock, ImmutableArray<BoundCatchBlock> catchBlocks, BoundBlock? finallyBlockOpt, LabelSymbol? finallyLabelOpt = null)
: this(syntax, tryBlock, catchBlocks, finallyBlockOpt, finallyLabelOpt, preferFaultHandler: false, hasErrors: false)
{
}
}
internal partial class BoundAddressOfOperator
{
public BoundAddressOfOperator(SyntaxNode syntax, BoundExpression operand, TypeSymbol type, bool hasErrors = false)
: this(syntax, operand, isManaged: false, type, hasErrors)
{
}
}
internal partial class BoundDagTemp
{
public BoundDagTemp(SyntaxNode syntax, TypeSymbol type, BoundDagEvaluation? source)
: this(syntax, type, source, index: 0, hasErrors: false)
{
}
public static BoundDagTemp ForOriginalInput(BoundExpression expr) => new BoundDagTemp(expr.Syntax, expr.Type!, source: null);
}
internal partial class BoundCompoundAssignmentOperator
{
public BoundCompoundAssignmentOperator(SyntaxNode syntax,
BinaryOperatorSignature @operator,
BoundExpression left,
BoundExpression right,
BoundValuePlaceholder? leftPlaceholder,
BoundExpression? leftConversion,
BoundValuePlaceholder? finalPlaceholder,
BoundExpression? finalConversion,
LookupResultKind resultKind,
TypeSymbol type,
bool hasErrors = false)
: this(syntax, @operator, left, right, leftPlaceholder, leftConversion, finalPlaceholder, finalConversion, resultKind, originalUserDefinedOperatorsOpt: default, type, hasErrors)
{
}
public BoundCompoundAssignmentOperator Update(BinaryOperatorSignature @operator,
BoundExpression left,
BoundExpression right,
BoundValuePlaceholder? leftPlaceholder,
BoundExpression? leftConversion,
BoundValuePlaceholder? finalPlaceholder,
BoundExpression? finalConversion,
LookupResultKind resultKind,
TypeSymbol type)
=> Update(@operator, left, right, leftPlaceholder, leftConversion, finalPlaceholder, finalConversion, resultKind, this.OriginalUserDefinedOperatorsOpt, type);
}
internal partial class BoundUnaryOperator
{
public BoundUnaryOperator(
SyntaxNode syntax,
UnaryOperatorKind operatorKind,
BoundExpression operand,
ConstantValue? constantValueOpt,
MethodSymbol? methodOpt,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
TypeSymbol type,
bool hasErrors = false) :
this(syntax, operatorKind, operand, constantValueOpt, methodOpt, constrainedToTypeOpt, resultKind, originalUserDefinedOperatorsOpt: default, type, hasErrors)
{
}
public BoundUnaryOperator Update(UnaryOperatorKind operatorKind,
BoundExpression operand,
ConstantValue? constantValueOpt,
MethodSymbol? methodOpt,
TypeSymbol? constrainedToTypeOpt,
LookupResultKind resultKind,
TypeSymbol type)
=> Update(operatorKind, operand, constantValueOpt, methodOpt, constrainedToTypeOpt, resultKind, this.OriginalUserDefinedOperatorsOpt, type);
}
internal partial class BoundIncrementOperator
{
public BoundIncrementOperator(
CSharpSyntaxNode syntax,
UnaryOperatorKind operatorKind,
BoundExpression operand,
MethodSymbol? methodOpt,
TypeSymbol? constrainedToTypeOpt,
BoundValuePlaceholder? operandPlaceholder,
BoundExpression? operandConversion,
BoundValuePlaceholder? resultPlaceholder,
BoundExpression? resultConversion,
LookupResultKind resultKind,
TypeSymbol type,
bool hasErrors = false) :
this(syntax, operatorKind, operand, methodOpt, constrainedToTypeOpt, operandPlaceholder, operandConversion, resultPlaceholder, resultConversion, resultKind, originalUserDefinedOperatorsOpt: default, type, hasErrors)
{
}
public BoundIncrementOperator Update(UnaryOperatorKind operatorKind, BoundExpression operand, MethodSymbol? methodOpt, TypeSymbol? constrainedToTypeOpt, BoundValuePlaceholder? operandPlaceholder, BoundExpression? operandConversion, BoundValuePlaceholder? resultPlaceholder, BoundExpression? resultConversion, LookupResultKind resultKind, TypeSymbol type)
{
return Update(operatorKind, operand, methodOpt, constrainedToTypeOpt, operandPlaceholder, operandConversion, resultPlaceholder, resultConversion, resultKind, this.OriginalUserDefinedOperatorsOpt, type);
}
}
}
|