diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx
index 571816c086a2a..6efec7573fa21 100644
--- a/src/Compilers/CSharp/Portable/CSharpResources.resx
+++ b/src/Compilers/CSharp/Portable/CSharpResources.resx
@@ -6078,6 +6078,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ
Nullable value type is null-checked and will throw if null.
+
Type '{0}' cannot be embedded because it has a re-abstraction of a member from base interface. Consider setting the 'Embed Interop Types' property to false.
diff --git a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
index b39db544fa391..f40f80e8731dd 100644
--- a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
+++ b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs
@@ -1232,7 +1232,7 @@ private void CompileMethod(
// Iterators handled in IteratorRewriter.cs
if (!methodSymbol.IsIterator)
{
- var boundStatementsWithNullCheck = LocalRewriter.ConstructNullCheckedStatementList(methodSymbol.Parameters, boundStatements, factory);
+ var boundStatementsWithNullCheck = LocalRewriter.TryConstructNullCheckedStatementList(methodSymbol.Parameters, boundStatements, factory);
if (!boundStatementsWithNullCheck.IsDefault)
{
@@ -1249,8 +1249,6 @@ private void CompileMethod(
}
if (!(methodSymbol is SynthesizedStaticConstructor cctor) || cctor.ShouldEmit(processedInitializers.BoundInitializers))
{
- CSharpSyntaxNode syntax = methodSymbol.GetNonNullSyntaxNode();
-
var boundBody = BoundStatementList.Synthesized(syntax, boundStatements);
var emittedBody = GenerateMethodBody(
diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
index f97a0765fa9a6..b70bd92b96564 100644
--- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
+++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs
@@ -1738,12 +1738,6 @@ internal enum ErrorCode
ERR_ReAbstractionInNoPIAType = 8750,
- ERR_NeedSpaceBetweenExclamationAndEquals = 8716,
- ERR_MustNullCheckInImplementation = 8717,
- ERR_NonNullableValueTypeIsNullChecked = 8718,
- WRN_NullCheckedHasDefaultNull = 8719,
- ERR_NullCheckingOnByRefParameter = 8720,
- WRN_NullCheckingOnNullableValueType = 8721,
#endregion diagnostics introduced for C# 8.0
#region diagnostics introduced in C# 9.0
@@ -1874,7 +1868,15 @@ internal enum ErrorCode
ERR_CopyConstructorWrongAccessibility = 8878,
ERR_NonPrivateAPIInRecord = 8879,
+ ERR_NeedSpaceBetweenExclamationAndEquals = 8890,
+ ERR_MustNullCheckInImplementation = 8891,
+ ERR_NonNullableValueTypeIsNullChecked = 8892,
+ WRN_NullCheckedHasDefaultNull = 8893,
+ ERR_NullCheckingOnByRefParameter = 8894,
+ WRN_NullCheckingOnNullableValueType = 8895,
+
#endregion diagnostics introduced for C# 9.0
+
// Note: you will need to re-generate compiler code after adding warnings (eng\generate-compiler-code.cmd)
}
}
diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
index fde67b2a4aaa1..2c92866da0b44 100644
--- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs
+++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs
@@ -187,7 +187,6 @@ internal enum MessageID
IDS_OverrideWithConstraints = MessageBase + 12761,
IDS_FeatureNestedStackalloc = MessageBase + 12762,
IDS_FeatureSwitchExpression = MessageBase + 12763,
- IDS_ParameterNullChecking = MessageBase + 12764,
IDS_FeatureAsyncUsing = MessageBase + 12764,
IDS_FeatureLambdaDiscardParameters = MessageBase + 12765,
IDS_FeatureLocalFunctionAttributes = MessageBase + 12766,
@@ -211,6 +210,8 @@ internal enum MessageID
IDS_FeatureNullPointerConstantPattern = MessageBase + 12783,
IDS_FeatureModuleInitializers = MessageBase + 12784,
IDS_FeatureTargetTypedConditional = MessageBase + 12785,
+
+ IDS_ParameterNullChecking = MessageBase + 12786,
}
// Message IDs may refer to strings that need to be localized.
diff --git a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
index 02fffc4aaba9f..e885b09608f2e 100644
--- a/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
+++ b/src/Compilers/CSharp/Portable/Generated/ErrorFacts.Generated.cs
@@ -227,8 +227,6 @@ public static bool IsWarning(ErrorCode code)
case ErrorCode.WRN_MissingNonNullTypesContextForAnnotationInGeneratedCode:
case ErrorCode.WRN_NullReferenceInitializer:
case ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint:
- case ErrorCode.WRN_NullCheckedHasDefaultNull:
- case ErrorCode.WRN_NullCheckingOnNullableValueType:
case ErrorCode.WRN_ParameterConditionallyDisallowsNull:
case ErrorCode.WRN_ShouldNotReturn:
case ErrorCode.WRN_TopLevelNullabilityMismatchInReturnTypeOnOverride:
@@ -248,6 +246,8 @@ public static bool IsWarning(ErrorCode code)
case ErrorCode.WRN_GivenExpressionAlwaysMatchesPattern:
case ErrorCode.WRN_IsPatternAlways:
case ErrorCode.WRN_NullabilityMismatchInReturnTypeOnPartial:
+ case ErrorCode.WRN_NullCheckedHasDefaultNull:
+ case ErrorCode.WRN_NullCheckingOnNullableValueType:
return true;
default:
return false;
diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs
index 840500bea13cd..a58cac6837109 100644
--- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter.cs
@@ -254,7 +254,8 @@ public override BoundNode VisitLambda(BoundLambda node)
try
{
_factory.CurrentFunction = node.Symbol;
- var visited = (BoundLambda)base.VisitLambda(node);
+ var visited = (BoundLambda)base.VisitLambda(node)!;
+
if (RewriteNullChecking(visited.Body) is BoundBlock newBody)
{
visited = visited.Update(visited.UnboundLambda, visited.Symbol, newBody, visited.Diagnostics, visited.Binder, visited.Type);
@@ -314,7 +315,8 @@ static bool hasReturnTypeOrParameter(LocalFunctionSymbol localFunction, Func ConstructNullCheckedStatementList(ImmutableArray parameters,
+ internal static ImmutableArray TryConstructNullCheckedStatementList(ImmutableArray parameters,
ImmutableArray existingStatements,
SyntheticBoundNodeFactory factory)
{
diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
index 9732f0c41f774..ad2354f139a4c 100644
--- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs
@@ -316,12 +316,9 @@ protected BoundStatement GenerateParameterStorage(LocalSymbol stateMachineVariab
}
}
- bodyBuilder.Add(GenerateStateMachineCreation(stateMachineVariable, frameType));
var builtBody = bodyBuilder.ToImmutableAndFree();
- ImmutableArray newBody = LocalRewriter.ConstructNullCheckedStatementList(method.Parameters, builtBody, F);
- return F.Block(
- ImmutableArray.Create(stateMachineVariable),
- newBody.IsDefault ? builtBody : newBody);
+ ImmutableArray newBody = LocalRewriter.TryConstructNullCheckedStatementList(method.Parameters, builtBody, F);
+ return newBody.IsDefault ? F.Block(builtBody) : F.Block(ImmutableArray.Create(stateMachineVariable), newBody);
}
protected SynthesizedImplementationMethod OpenMethodImplementation(
diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs
index daace1cc43853..5da3a9cac1f99 100644
--- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs
@@ -1487,6 +1487,7 @@ internal ImmutableArray MakeTempsForDiscardArguments(ImmutableA
return arguments;
}
+#nullable disable
internal BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewrittenExpr, BinaryOperatorKind operatorKind)
{
Debug.Assert((operatorKind == BinaryOperatorKind.Equal) || (operatorKind == BinaryOperatorKind.NotEqual) ||
@@ -1531,7 +1532,7 @@ internal BoundExpression MakeNullCheck(SyntaxNode syntax, BoundExpression rewrit
}
if (operatorKind == BinaryOperatorKind.NullableNullEqual || operatorKind == BinaryOperatorKind.NullableNullNotEqual)
{
- return RewriteNullableNullEquality(syntax, operatorKind, rewrittenExpr, Literal(ConstantValue.Null, objectType), boolType);
+ return RewriteNullableNullEquality(syntax, operatorKind, rewrittenExpr, Literal(ConstantValue.Null, objectType), boolType);
}
else
{
@@ -1615,5 +1616,7 @@ internal BoundExpression RewriteNullableNullEquality(
return result;
}
+ // PROTOTYPE(BangBang): Re-enable annotations
+#nullable enable
}
}
diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
index 5f8dcfd7c2cd9..4c5ec5a9c9621 100644
--- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
+++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs
@@ -6923,7 +6923,7 @@ private FunctionPointerTypeSyntax ParseFunctionPointerTypeSyntax()
var lessThanTokenError = WithAdditionalDiagnostics(SyntaxFactory.MissingToken(SyntaxKind.LessThanToken), GetExpectedTokenError(SyntaxKind.LessThanToken, SyntaxKind.None));
var missingTypes = _pool.AllocateSeparated();
var missingTypeName = CreateMissingIdentifierName();
- var missingType = SyntaxFactory.Parameter(attributeLists: default, modifiers: default, missingTypeName, identifier: CreateMissingIdentifierToken(), @default: null);
+ var missingType = SyntaxFactory.Parameter(attributeLists: default, modifiers: default, missingTypeName, identifier: CreateMissingIdentifierToken(), exclamationToken: null, @default: null);
missingTypes.Add(missingType);
// Handle the simple case of delegate*>. We don't try to deal with any variation of delegate*invalid>, as
// we don't know for sure that the expression isn't a relational with something else.
@@ -6949,7 +6949,7 @@ private FunctionPointerTypeSyntax ParseFunctionPointerTypeSyntax()
ParseParameterModifiers(modifiers, isFunctionPointerParameter: true);
var parameterType = ParseTypeOrVoid();
- types.Add(SyntaxFactory.Parameter(attributeLists: default, modifiers, parameterType, identifier: CreateMissingIdentifierToken(), @default: null));
+ types.Add(SyntaxFactory.Parameter(attributeLists: default, modifiers, parameterType, identifier: CreateMissingIdentifierToken(), exclamationToken: null, @default: null));
if (skipBadFunctionPointerParameterListTokens() == PostSkipAction.Abort)
{
@@ -10413,26 +10413,6 @@ private bool IsPossibleAnonymousMethodExpression()
tokenIndex++;
}
- if (precedence <= Precedence.Lambda)
- {
- SyntaxKind token1 = this.PeekToken(1).Kind;
- if (token1 == SyntaxKind.EqualsGreaterThanToken)
- {
- return true;
- }
-
- if (token1 == SyntaxKind.ExclamationToken && this.PeekToken(2).Kind == SyntaxKind.EqualsGreaterThanToken)
- {
- return true;
- }
-
- // Broken case but error will be added in lambda function.
- if (token1 == SyntaxKind.ExclamationEqualsToken && this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken)
- {
- return true;
- }
- }
-
return this.PeekToken(tokenIndex).Kind == SyntaxKind.DelegateKeyword;
}
@@ -11261,6 +11241,22 @@ private bool IsPossibleLambdaExpression(Precedence precedence)
return false;
}
+ SyntaxKind token1 = this.PeekToken(1).Kind;
+ if (token1 == SyntaxKind.EqualsGreaterThanToken)
+ {
+ return true;
+ }
+ if (token1 == SyntaxKind.ExclamationToken && this.PeekToken(2).Kind == SyntaxKind.EqualsGreaterThanToken)
+ {
+ return true;
+ }
+
+ // Broken case but error will be added in lambda function.
+ if (token1 == SyntaxKind.ExclamationEqualsToken && this.PeekToken(2).Kind == SyntaxKind.GreaterThanToken)
+ {
+ return true;
+ }
+
// If we start with `static` or `async static` then just jump past those and do the
// analysis after that point. Note, we don't just blindly consume `async` in `static
// async` because that `async` may not be a modifier (it may just be an identifier) and
diff --git a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
index e07f767c5f9e7..f5be02f64a306 100644
--- a/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
+++ b/src/Compilers/CSharp/Portable/PublicAPI.Unshipped.txt
@@ -5,6 +5,9 @@ Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax.AddModifier
Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax.Update(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.SyntaxToken delegateKeyword, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterListSyntax parameterList, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax block, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousMethodExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax
+Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.ExclamationToken.get -> Microsoft.CodeAnalysis.SyntaxToken
+Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.Update(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax
+Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax.WithExclamationToken(Microsoft.CodeAnalysis.SyntaxToken exclamationToken) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax.DefaultKeyword.get -> Microsoft.CodeAnalysis.SyntaxToken
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax.Update(Microsoft.CodeAnalysis.SyntaxToken defaultKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax.WithDefaultKeyword(Microsoft.CodeAnalysis.SyntaxToken defaultKeyword) -> Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax
@@ -16,6 +19,7 @@ Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedLambdaExpressionSyntax.WithMod
Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax.AddModifiers(params Microsoft.CodeAnalysis.SyntaxToken[] items) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax.Update(Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax parameter, Microsoft.CodeAnalysis.SyntaxToken arrowToken, Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax block, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expressionBody) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax
Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax.WithModifiers(Microsoft.CodeAnalysis.SyntaxTokenList modifiers) -> Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax
+static Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Parameter(Microsoft.CodeAnalysis.SyntaxList attributeLists, Microsoft.CodeAnalysis.SyntaxTokenList modifiers, Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax type, Microsoft.CodeAnalysis.SyntaxToken identifier, Microsoft.CodeAnalysis.SyntaxToken exclamationToken, Microsoft.CodeAnalysis.CSharp.Syntax.EqualsValueClauseSyntax default) -> Microsoft.CodeAnalysis.CSharp.Syntax.ParameterSyntax
Microsoft.CodeAnalysis.CSharp.SyntaxKind.DefaultConstraint = 9057 -> Microsoft.CodeAnalysis.CSharp.SyntaxKind
abstract Microsoft.CodeAnalysis.CSharp.Syntax.AnonymousFunctionExpressionSyntax.Modifiers.get -> Microsoft.CodeAnalysis.SyntaxTokenList
override Microsoft.CodeAnalysis.CSharp.CSharpSyntaxRewriter.VisitDefaultConstraint(Microsoft.CodeAnalysis.CSharp.Syntax.DefaultConstraintSyntax node) -> Microsoft.CodeAnalysis.SyntaxNode
diff --git a/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerParameterSymbol.cs
index c2aebe52064fa..c4872ddd7574b 100644
--- a/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerParameterSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/FunctionPointers/FunctionPointerParameterSymbol.cs
@@ -67,6 +67,7 @@ internal int MethodHashCode()
public override bool IsDiscard => false;
public override bool IsParams => false;
public override bool IsImplicitlyDeclared => true;
+ public override bool IsNullChecked => false;
internal override MarshalPseudoCustomAttributeData? MarshallingInformation => null;
internal override bool IsMetadataOptional => false;
internal override bool IsMetadataIn => RefKind == RefKind.In;
diff --git a/src/Compilers/CSharp/Portable/Symbols/PublicModel/ParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/PublicModel/ParameterSymbol.cs
index e0cfc28079648..dbcea4a4b2d03 100644
--- a/src/Compilers/CSharp/Portable/Symbols/PublicModel/ParameterSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/PublicModel/ParameterSymbol.cs
@@ -60,6 +60,8 @@ IParameterSymbol IParameterSymbol.OriginalDefinition
bool IParameterSymbol.IsParams => _underlying.IsParams;
+ bool IParameterSymbol.IsNullChecked => _underlying.IsNullChecked;
+
bool IParameterSymbol.IsOptional => _underlying.IsOptional;
bool IParameterSymbol.IsThis => _underlying.IsThis;
diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs
index f5588c408cab7..0259140149509 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Source/ParameterHelpers.cs
@@ -194,18 +194,7 @@ private static ImmutableArray MakeParameters ConditionallyCreateInModifiers(RefKind refKind, bool addRefReadOnlyModifier, Binder binder, DiagnosticBag diagnostics, SyntaxNode syntax)
{
if (addRefReadOnlyModifier && refKind == RefKind.In)
@@ -791,6 +778,5 @@ private static ImmutableArray CreateModifiers(WellKnownType modi
var modifierType = binder.GetWellKnownType(modifier, diagnostics, syntax);
return ImmutableArray.Create(CSharpCustomModifier.CreateRequired(modifierType));
}
->>>>>>> origin/master
}
}
diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs
index d5573595f4cf6..047a00ad68b0d 100644
--- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs
+++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedParameterSymbol.cs
@@ -271,8 +271,9 @@ public SynthesizedComplexParameterSymbol(
RefKind refKind,
string name,
ImmutableArray refCustomModifiers,
- SourceComplexParameterSymbol? baseParameterForAttributes)
- : base(container, type, ordinal, refKind, name)
+ SourceComplexParameterSymbol? baseParameterForAttributes,
+ bool isNullChecked)
+ : base(container, type, ordinal, refKind, name, isNullChecked)
{
Debug.Assert(!refCustomModifiers.IsDefault);
Debug.Assert(!refCustomModifiers.IsEmpty || baseParameterForAttributes is object);
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
index 2d72ca040048e..9e92067b054a5 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf
@@ -537,6 +537,16 @@
Seznam parametrů může mít jenom částečná deklarace jednoho záznamu.
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
Omezení new() nejde používat s omezením unmanaged.
@@ -567,6 +577,11 @@
Typ příjemce {0} není platný typ záznamu.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
Očekávala se hodnota enable, disable nebo restore.
@@ -1506,6 +1526,11 @@
omezení pro metody přepsání a explicitní implementace rozhraní
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<výraz throw>
@@ -2096,6 +2121,26 @@
Literál null nejde převést na odkazový typ, který nemůže mít hodnotu null.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
V parametru {0} v {1} může být argument s odkazem null.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
index 24b7bfd937b38..400acce3f52ca 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf
@@ -537,6 +537,16 @@
Nur eine partielle Deklaration eines einzelnen Datensatzes darf eine Parameterliste aufweisen.
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
Die new()-Einschränkung kann nicht mit der unmanaged-Einschränkung verwendet werden.
@@ -567,6 +577,11 @@
Der Empfängertyp "{0}" ist kein gültiger Datensatztyp.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
"enable", "disable" oder "restore" erwartet.
@@ -1506,6 +1526,11 @@
Einschränkungen für Außerkraftsetzung und explizite Schnittstellenimplementierungsmethoden
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
throw-Ausdruck
@@ -2096,6 +2121,26 @@
Ein NULL-Literal kann nicht in einen Non-Nullable-Verweistyp konvertiert werden.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Mögliches Nullverweisargument für den Parameter "{0}" in "{1}".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
index 468c9875f8442..9f7899dfeff16 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf
@@ -537,6 +537,16 @@
Solo una declaración parcial de un registro puede tener una lista de parámetros
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
La restricción "new()" no se puede utilizar con la restricción "unmanaged"
@@ -567,6 +577,11 @@
El tipo de receptor "{0}" no es un tipo de registro válido.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
Se esperaba "enable", "disable" o "restore".
@@ -1506,6 +1526,11 @@
restricciones para métodos de implementación de interfaz explícita e invalidación
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<expresión throw>
@@ -2096,6 +2121,26 @@
No se puede convertir un literal NULL en un tipo de referencia que no acepta valores NULL.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Posible argumento de referencia nulo para el parámetro "{0}" en "{1}".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
index 7fad19657ce32..a8ce979a1e5e0 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf
@@ -537,6 +537,16 @@
Seule une déclaration partielle d'un seul enregistrement peut avoir une liste de paramètres
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
La contrainte 'new()' ne peut pas être utilisée avec la contrainte 'unmanaged'
@@ -567,6 +577,11 @@
Le récepteur de type '{0}' n'est pas un type d'enregistrement valide.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
'enable', 'disable' ou 'restore' attendu
@@ -1506,6 +1526,11 @@
contraintes des méthodes d'implémentation d'interface par remplacement et explicites
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<expression throw>
@@ -2096,6 +2121,26 @@
Impossible de convertir un littéral ayant une valeur null en type référence non-nullable.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Existence possible d'un argument de référence null pour le paramètre '{0}' dans '{1}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
index 28c3739cf1ac9..e7aad044cd71b 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf
@@ -537,6 +537,16 @@
Solo una dichiarazione parziale di singolo record può includere un elenco di parametri
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
Non è possibile usare il vincolo 'new()' con il vincolo 'unmanaged'
@@ -567,6 +577,11 @@
Il tipo di ricevitore '{0}' non è un tipo di record valido.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
È previsto 'enable', 'disable' o 'restore'
@@ -1506,6 +1526,11 @@
vincoli per i metodi di override e di implementazione esplicita dell'interfaccia
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<espressione throw>
@@ -2096,6 +2121,26 @@
Non è possibile convertire il valore letterale Null in tipo riferimento che non ammette i valori Null.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Possibile argomento di riferimento Null per il parametro '{0}' in '{1}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
index f6080b15f0976..13bbe6eb71f18 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf
@@ -537,6 +537,16 @@
1 つのレコードの部分宣言のみがパラメーター リストを持つことができます
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
new()' 制約は 'unmanaged' 制約と一緒には使用できません
@@ -567,6 +577,11 @@
レシーバーの種類 '{0}' は有効なレコードの種類ではありません。
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
'enable'、'disable'、'restore' のいずれかが必要でした
@@ -1506,6 +1526,11 @@
オーバーライドおよび明示的なインターフェイスの実装メソッドの制約
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<スロー式>
@@ -2096,6 +2121,26 @@
null リテラルを null 非許容参照型に変換できません。
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
'{1}' 内のパラメーター '{0}' に Null 参照引数がある可能性があります。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
index 427cbbdf0451c..9da7174302751 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf
@@ -537,6 +537,16 @@
단일 레코드 partial 선언에만 매개 변수 목록을 사용할 수 있습니다.
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
new()' 제약 조건은 'unmanaged' 제약 조건과 함께 사용할 수 없습니다.
@@ -567,6 +577,11 @@
수신기 형식 '{0}'이(가) 유효한 레코드 형식이 아닙니다.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
'enable', 'disable' 또는 'restore'가 필요합니다.
@@ -1506,6 +1526,11 @@
재정의 및 명시적 인터페이스 구현 메서드에 대한 제약 조건
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<Throw 식>
@@ -2096,6 +2121,26 @@
Null 리터럴을 null을 허용하지 않는 참조 형식으로 변환할 수 없습니다.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
'{1}'의 매개 변수 '{0}'에 대한 가능한 null 참조 인수입니다.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
index 535fbddfc7158..971df013a5f6f 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf
@@ -537,6 +537,16 @@
Tylko pojedyncza częściowa deklaracja rekordu może mieć listę parametrów
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
Ograniczenie „new()” nie może być używane z ograniczeniem „unmanaged”
@@ -567,6 +577,11 @@
Typ odbiorcy „{0}” nie jest prawidłowym typem rekordu.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
Oczekiwano opcji „enable”, „disable” lub „restore”
@@ -1506,6 +1526,11 @@
ograniczenia dla przesłonięć i jawnych metod implementacji interfejsu
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<wyrażenie throw>
@@ -2096,6 +2121,26 @@
Nie można przekonwertować literału o wartości null na nienullowalny typ referencyjny.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Możliwy argument odwołania o wartości null dla parametru „{0}” w „{1}”.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
index 0340587a59fd5..b6d018e91683a 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf
@@ -537,6 +537,16 @@
Apenas uma declaração parcial de registro único pode ter uma lista de parâmetros
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
A restrição 'new()' não pode ser usada com a restrição 'unmanaged'
@@ -567,6 +577,11 @@
O tipo de receptor '{0}' não é um tipo de registro válido.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
Esperava-se 'enable', 'disable' ou 'restore'
@@ -1505,6 +1525,11 @@
restrições para métodos de substituição e de implementação explícita da interface
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<expressão throw>
@@ -2095,6 +2120,26 @@
Não é possível converter um literal nulo em um tipo de referência não anulável.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Possível argumento de referência nula para o parâmetro '{0}' em '{1}'.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
index 60f46d0f4b3cb..2f454e5eb1acf 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf
@@ -537,6 +537,16 @@
Только частичное объявление отдельной записи может иметь список параметров.
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
Ограничение "new()" невозможно использовать вместе с ограничением "unmanaged"
@@ -567,6 +577,11 @@
Тип получателя "{0}" не является допустимым типом записи.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
Ожидается "enable", "disable" или "restore"
@@ -1506,6 +1526,11 @@
ограничения для методов переопределения и явной реализации интерфейса
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<выражение throw>
@@ -2096,6 +2121,26 @@
Литерал, равный NULL, не может быть преобразован в ссылочный тип, не допускающий значение NULL.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
Возможно, аргумент-ссылка, допускающий значение NULL, для параметра "{0}" в "{1}".
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
index d7535fdf13d7d..04c531aab5748 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf
@@ -537,6 +537,16 @@
Yalnızca tek kaydın kısmi bildiriminde parametre listesi olabilir
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
'new()' kısıtlaması, 'unmanaged' kısıtlamasıyla kullanılamaz
@@ -567,6 +577,11 @@
'{0}' alıcı türü geçerli bir kayıt türü değil.
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
'enable', 'disable' veya 'restore' bekleniyor
@@ -1506,6 +1526,11 @@
geçersiz kılma ve açık arabirim uygulama yöntemleri için kısıtlamalar
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<throw ifadesi>
@@ -2096,6 +2121,26 @@
Null sabit değer, boş değer atanamayan başvuru türüne dönüştürülemiyor.
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
'{1}' içindeki '{0}' parametresi için olası null başvuru bağımsız değişkeni.
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
index 40db8f961e779..16a2938e2b00e 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf
@@ -537,6 +537,16 @@
只有一个记录分部声明可以具有参数列表
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
"new()" 约束不能与 "unmanaged" 约束一起使用
@@ -567,6 +577,11 @@
指定的接收器类型“{0}”不是有效的记录类型。
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
应为 "enable"、"disable" 或 "restore"
@@ -1506,6 +1526,11 @@
重写和显式接口实现方法的约束
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<throw 表达式>
@@ -2096,6 +2121,26 @@
无法将 null 文本转换为不可为 null 的引用类型。
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
“{1}”中“{0}”形参的可能的 null 引用实参。
diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
index e617fc714b865..9b1b2f09c857a 100644
--- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
+++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf
@@ -537,6 +537,16 @@
只有一筆記錄可以在部分宣告中包含參數清單
+
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+ Parameter '{0}' can only have exclamation-point null checking in implementation methods.
+
+
+
+ Space required between '!' and '=' here.
+ Space required between '!' and '=' here.
+
+
The 'new()' constraint cannot be used with the 'unmanaged' constraint
new()' 條件約束不能和 'unmanaged' 條件約束一起使用
@@ -567,6 +577,11 @@
接收器類型 '{0}' 不是有效的記錄類型。
+
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+ Parameter '{0}' is a non-nullable value type and cannot be null-checked.
+
+
Record member '{0}' must be private.
Record member '{0}' must be private.
@@ -587,6 +602,11 @@
'{0}' must allow overriding because the containing record is not sealed.
+
+ By-reference parameter '{0}' cannot be null-checked.
+ By-reference parameter '{0}' cannot be null-checked.
+
+
Expected 'enable', 'disable', or 'restore'
應為 'enable'、'disable' 或 'restore'
@@ -1506,6 +1526,11 @@
適用於覆寫和明確介面實作方法的條件約束
+
+ parameter null-checking
+ parameter null-checking
+
+
<throw expression>
<throw 運算式>
@@ -2096,6 +2121,26 @@
無法將 null 常值轉換成不可為 Null 的參考型別。
+
+ Parameter '{0}' is null-checked but is null by default.
+ Parameter '{0}' is null-checked but is null by default.
+
+
+
+ Parameter is null-checked but is null by default.
+ Parameter is null-checked but is null by default.
+
+
+
+ Nullable value type '{0}' is null-checked and will throw if null.
+ Nullable value type '{0}' is null-checked and will throw if null.
+
+
+
+ Nullable value type is null-checked and will throw if null.
+ Nullable value type is null-checked and will throw if null.
+
+
Possible null reference argument for parameter '{0}' in '{1}'.
'{1}' 中的參數 '{0}' 可能有 Null 參考引數。
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCheckedParameterTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCheckedParameterTests.cs
index 0c3e0513a48d8..733ca39e17606 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCheckedParameterTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenNullCheckedParameterTests.cs
@@ -1,4 +1,6 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+// 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 Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
@@ -1206,13 +1208,13 @@ public static void Main()
{
// Code size 29 (0x1d)
.maxstack 3
- IL_0000: ldarg.1
- IL_0001: brtrue.s IL_000e
- IL_0003: ldstr ""s""
- IL_0008: newobj ""System.ArgumentNullException..ctor(string)""
- IL_000d: throw
- IL_000e: ldc.i4.s -2
- IL_0010: newobj ""C.d__0..ctor(int)""
+ IL_0000: ldc.i4.s -2
+ IL_0002: newobj ""C.d__0..ctor(int)""
+ IL_0007: ldarg.1
+ IL_0008: brtrue.s IL_0015
+ IL_000a: ldstr ""s""
+ IL_000f: newobj ""System.ArgumentNullException..ctor(string)""
+ IL_0014: throw
IL_0015: dup
IL_0016: ldarg.1
IL_0017: stfld ""string C.d__0.<>3__s""
@@ -1245,13 +1247,13 @@ IEnumerable GetChars(string s!)
{
// Code size 29 (0x1d)
.maxstack 3
- IL_0000: ldarg.0
- IL_0001: brtrue.s IL_000e
- IL_0003: ldstr ""s""
- IL_0008: newobj ""System.ArgumentNullException..ctor(string)""
- IL_000d: throw
- IL_000e: ldc.i4.s -2
- IL_0010: newobj ""Iterators.<g__GetChars|0_0>d..ctor(int)""
+ IL_0000: ldc.i4.s -2
+ IL_0002: newobj ""Iterators.<g__GetChars|0_0>d..ctor(int)""
+ IL_0007: ldarg.0
+ IL_0008: brtrue.s IL_0015
+ IL_000a: ldstr ""s""
+ IL_000f: newobj ""System.ArgumentNullException..ctor(string)""
+ IL_0014: throw
IL_0015: dup
IL_0016: ldarg.0
IL_0017: stfld ""string Iterators.<g__GetChars|0_0>d.<>3__s""
@@ -1284,17 +1286,17 @@ IEnumerator GetChars(string s!)
{
// Code size 28 (0x1c)
.maxstack 3
- IL_0000: ldarg.0
- IL_0001: brtrue.s IL_000e
- IL_0003: ldstr ""s""
- IL_0008: newobj ""System.ArgumentNullException..ctor(string)""
- IL_000d: throw
- IL_000e: ldc.i4.0
- IL_000f: newobj ""Iterators.<g__GetChars|0_0>d..ctor(int)""
+ IL_0000: ldc.i4.0
+ IL_0001: newobj ""Iterators.<g__GetChars|0_0>d..ctor(int)""
+ IL_0006: ldarg.0
+ IL_0007: brtrue.s IL_0014
+ IL_0009: ldstr ""s""
+ IL_000e: newobj ""System.ArgumentNullException..ctor(string)""
+ IL_0013: throw
IL_0014: dup
IL_0015: ldarg.0
IL_0016: stfld ""string Iterators.<g__GetChars|0_0>d.s""
- IL_001b: ret
+ IL_001b: ret
}");
}
@@ -1403,14 +1405,14 @@ static IEnumerable GetChars(string s!)
CompileAndVerify(source, parseOptions: TestOptions.RegularPreview).VerifyIL("C.GetChars(string)", @"
{
// Code size 22 (0x16)
- .maxstack 1
- IL_0000: ldarg.0
- IL_0001: brtrue.s IL_000e
- IL_0003: ldstr ""s""
- IL_0008: newobj ""System.ArgumentNullException..ctor(string)""
- IL_000d: throw
- IL_000e: ldc.i4.s -2
- IL_0010: newobj ""C.d__1..ctor(int)""
+ .maxstack 2
+ IL_0000: ldc.i4.s -2
+ IL_0002: newobj ""C.d__1..ctor(int)""
+ IL_0007: ldarg.0
+ IL_0008: brtrue.s IL_0015
+ IL_000a: ldstr ""s""
+ IL_000f: newobj ""System.ArgumentNullException..ctor(string)""
+ IL_0014: throw
IL_0015: ret
}");
}
@@ -1431,14 +1433,14 @@ static IEnumerator GetChars(string s!)
CompileAndVerify(source, parseOptions: TestOptions.RegularPreview).VerifyIL("C.GetChars(string)", @"
{
// Code size 21 (0x15)
- .maxstack 1
- IL_0000: ldarg.0
- IL_0001: brtrue.s IL_000e
- IL_0003: ldstr ""s""
- IL_0008: newobj ""System.ArgumentNullException..ctor(string)""
- IL_000d: throw
- IL_000e: ldc.i4.0
- IL_000f: newobj ""C.d__1..ctor(int)""
+ .maxstack 2
+ IL_0000: ldc.i4.0
+ IL_0001: newobj ""C.d__1..ctor(int)""
+ IL_0006: ldarg.0
+ IL_0007: brtrue.s IL_0014
+ IL_0009: ldstr ""s""
+ IL_000e: newobj ""System.ArgumentNullException..ctor(string)""
+ IL_0013: throw
IL_0014: ret
}");
}
diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTest_INullCheckedParameters.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTest_INullCheckedParameters.cs
deleted file mode 100644
index 9ffbbd67ac852..0000000000000
--- a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTest_INullCheckedParameters.cs
+++ /dev/null
@@ -1,2603 +0,0 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-using System.Linq;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
-using Microsoft.CodeAnalysis.FlowAnalysis;
-using Microsoft.CodeAnalysis.Operations;
-using Microsoft.CodeAnalysis.Test.Utilities;
-using Xunit;
-
-namespace Microsoft.CodeAnalysis.CSharp.UnitTests
-{
- public partial class IOperationTests : SemanticModelTestBase
- {
- [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)]
- [Fact]
- public void NullCheckedMethodDeclarationIOp()
- {
- var source = @"
-public class C
-{
- public void M(string input!) { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
-
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... input!) { }')
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... input!) { }')
- Left:
- IParameterReferenceOperation: input (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... input!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public void ... input!) { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... input!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... input!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""input"", IsImplicit) (Syntax: 'public void ... input!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_OneNullCheckedManyParams()
- {
- var source = @"
-public class C
-{
- public void M(string x, string y!) { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
-
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... ing y!) { }')
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... ing y!) { }')
- Left:
- IParameterReferenceOperation: y (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... ing y!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public void ... ing y!) { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... ing y!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... ing y!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""y"", IsImplicit) (Syntax: 'public void ... ing y!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_OneNullCheckedParamWithStringOpt()
- {
- var source = @"
-public class C
-{
- public void M(string name! = ""rose"") { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
-
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... ""rose"") { }')
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
-Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
- Left:
- IParameterReferenceOperation: name (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public void ... ""rose"") { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""name"", IsImplicit) (Syntax: 'public void ... ""rose"") { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedOperator()
- {
- var source = @"
-public class Box
-{
- public static int operator+ (Box b!, Box c)
- {
- return 2;
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
-
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public stat ... }')
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IReturnOperation (OperationKind.Return, Type: null) (Syntax: 'return 2;')
- ReturnedValue:
- ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public stat ... }')
- Left:
- IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: Box, IsImplicit) (Syntax: 'public stat ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: Box, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public stat ... }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public stat ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public stat ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""b"", IsImplicit) (Syntax: 'public stat ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Return) Block[B4]
- ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact(Skip = "PROTOTYPE")]
- public void TestIOp_NullCheckedIndexedProperty()
- {
- // PROTOTYPE
- var source = @"
-public class C
-{
- public string this[string index!] => null;
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '=> null')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'null')
- ReturnedValue:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- Operand:
- ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"");
- }
-
- [Fact]
- public void TestIOp_NullCheckedIndexedGetterSetter()
- {
- var source = @"
-public class C
-{
- private object[] items = {'h', ""hello""};
- public string this[object item!]
- {
- /**/get
- {
- return items[0].ToString();
- }/* */
- set
- {
- items[0] = value;
- }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'set ... }')
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'items[0] = value;')
- Expression:
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Object) (Syntax: 'items[0] = value')
- Left:
- IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
- Array reference:
- IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
- Indices(1):
- ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
- Right:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'value')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- Operand:
- IParameterReferenceOperation: value (OperationKind.ParameterReference, Type: System.String) (Syntax: 'value')
- ExpressionBody:
- null");
- var expected = @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'get ... }')
- Left:
- IParameterReferenceOperation: item (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'get ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'get ... }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'get ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'get ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""item"", IsImplicit) (Syntax: 'get ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Return) Block[B4]
- IInvocationOperation (virtual System.String System.Object.ToString()) (OperationKind.Invocation, Type: System.String) (Syntax: 'items[0].ToString()')
- Instance Receiver:
- IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
- Array reference:
- IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
- Indices(1):
- ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
- Arguments(0)
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)";
- VerifyFlowGraphAndDiagnosticsForTest(source, expected, DiagnosticDescription.None, parseOptions: TestOptions.RegularPreview);
- }
-
- [Fact]
- public void TestIOp_NullCheckedIndexedGetterExpression()
- {
- var source = @"
-public class C
-{
- private object[] items = {'h', ""hello""};
- public string this[object item!]
- {
- /**/get => items[0].ToString();/* */
- set
- {
- items[0] = value;
- }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'set ... }')
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'items[0] = value;')
- Expression:
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Object) (Syntax: 'items[0] = value')
- Left:
- IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
- Array reference:
- IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
- Indices(1):
- ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
- Right:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'value')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- Operand:
- IParameterReferenceOperation: value (OperationKind.ParameterReference, Type: System.String) (Syntax: 'value')
- ExpressionBody:
- null");
- var expected = @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'get => item ... ToString();')
- Left:
- IParameterReferenceOperation: item (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'get => item ... ToString();')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'get => item ... ToString();')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'get => item ... ToString();')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'get => item ... ToString();')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""item"", IsImplicit) (Syntax: 'get => item ... ToString();')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Return) Block[B4]
- IInvocationOperation (virtual System.String System.Object.ToString()) (OperationKind.Invocation, Type: System.String) (Syntax: 'items[0].ToString()')
- Instance Receiver:
- IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
- Array reference:
- IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
- Indices(1):
- ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
- Arguments(0)
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)
-";
- VerifyFlowGraphAndDiagnosticsForTest(source, expected, DiagnosticDescription.None, parseOptions: TestOptions.RegularPreview);
- }
-
- [Fact]
- public void TestIOp_NullCheckedIndexedSetter()
- {
- var source = @"
-public class C
-{
- public string this[object item!] { /**/set { }/* */ }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'set { }')
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
- var expected = @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'set { }')
- Left:
- IParameterReferenceOperation: item (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'set { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'set { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'set { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'set { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""item"", IsImplicit) (Syntax: 'set { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)";
- VerifyFlowGraphAndDiagnosticsForTest(source, expected, DiagnosticDescription.None, parseOptions: TestOptions.RegularPreview);
- }
-
- [Fact]
- public void TestIOp_NullCheckedLambda()
- {
- var source = @"
-using System;
-class C
-{
- public void M()
- {
- Func func1 = x! => x;
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
- BlockBody:
- IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- Locals: Local_1: System.Func func1
- IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'Func x;')
- IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'Func x')
- Declarators:
- IVariableDeclaratorOperation (Symbol: System.Func func1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'func1 = x! => x')
- Initializer:
- IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= x! => x')
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 'x! => x')
- Target:
- IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: 'x! => x')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
- ReturnedValue:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Initializer:
- null
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
-Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
-.locals {R1}
-{
- Locals: [System.Func func1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: 'func1 = x! => x')
- Left:
- ILocalReferenceOperation: func1 (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsImplicit) (Syntax: 'func1 = x! => x')
- Right:
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 'x! => x')
- Target:
- IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: 'x! => x')
- {
- Block[B0#A0] - Entry
- Statements (0)
- Next (Regular) Block[B1#A0]
- Block[B1#A0] - Block
- Predecessors: [B0#A0]
- Statements (0)
- Jump if False (Regular) to Block[B3#A0]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'x! => x')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'x! => x')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'x! => x')
- Next (Regular) Block[B2#A0]
- Block[B2#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'x! => x')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'x! => x')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'x! => x')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Return) Block[B4#A0]
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Block[B4#A0] - Exit
- Predecessors: [B3#A0]
- Statements (0)
- }
- Next (Regular) Block[B2]
- Leaving: {R1}
-}
-Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedInLambdaWithManyParameters()
- {
- var source = @"
-using System;
-class C
-{
- public void M()
- {
- Func func1 = (x!, y) => x;
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
- BlockBody:
- IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- Locals: Local_1: System.Func func1
- IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'Func x;')
- IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'Func x')
- Declarators:
- IVariableDeclaratorOperation (Symbol: System.Func func1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'func1 = (x!, y) => x')
- Initializer:
- IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= (x!, y) => x')
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '(x!, y) => x')
- Target:
- IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: '(x!, y) => x')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
- ReturnedValue:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Initializer:
- null
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Locals: [System.Func func1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: 'func1 = (x!, y) => x')
- Left:
- ILocalReferenceOperation: func1 (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsImplicit) (Syntax: 'func1 = (x!, y) => x')
- Right:
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '(x!, y) => x')
- Target:
- IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: '(x!, y) => x')
- {
- Block[B0#A0] - Entry
- Statements (0)
- Next (Regular) Block[B1#A0]
- Block[B1#A0] - Block
- Predecessors: [B0#A0]
- Statements (0)
- Jump if False (Regular) to Block[B3#A0]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: '(x!, y) => x')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: '(x!, y) => x')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: '(x!, y) => x')
- Next (Regular) Block[B2#A0]
- Block[B2#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: '(x!, y) => x')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: '(x!, y) => x')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: '(x!, y) => x')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Return) Block[B4#A0]
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Block[B4#A0] - Exit
- Predecessors: [B3#A0]
- Statements (0)
- }
- Next (Regular) Block[B2]
- Leaving: {R1}
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedUnnamedVariableInLambda()
- {
- var source = @"
-using System;
-class C
-{
- public void M()
- {
- Func func1 = _! => null;
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
- BlockBody:
- IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- Locals: Local_1: System.Func func1
- IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'Func null;')
- IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'Func null')
- Declarators:
- IVariableDeclaratorOperation (Symbol: System.Func func1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'func1 = _! => null')
- Initializer:
- IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= _! => null')
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '_! => null')
- Target:
- IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: '_! => null')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'null')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'null')
- ReturnedValue:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- Operand:
- ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')
- Initializer:
- null
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Locals: [System.Func func1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: 'func1 = _! => null')
- Left:
- ILocalReferenceOperation: func1 (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsImplicit) (Syntax: 'func1 = _! => null')
- Right:
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '_! => null')
- Target:
- IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: '_! => null')
- {
- Block[B0#A0] - Entry
- Statements (0)
- Next (Regular) Block[B1#A0]
- Block[B1#A0] - Block
- Predecessors: [B0#A0]
- Statements (0)
- Jump if False (Regular) to Block[B3#A0]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: '_! => null')
- Left:
- IParameterReferenceOperation: _ (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: '_! => null')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: '_! => null')
- Next (Regular) Block[B2#A0]
- Block[B2#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: '_! => null')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: '_! => null')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""_"", IsImplicit) (Syntax: '_! => null')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Return) Block[B4#A0]
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- (ImplicitReference)
- Operand:
- ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')
- Block[B4#A0] - Exit
- Predecessors: [B3#A0]
- Statements (0)
- }
- Next (Regular) Block[B2]
- Leaving: {R1}
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedTwoExpressionBodyLambdas()
- {
- var source = @"
-using System;
-class C
-{
- public Func M(string s1!) => s2! => s2 + s1;
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public Func ... => s2 + s1;')
- BlockBody:
- null
- ExpressionBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '=> s2! => s2 + s1')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 's2! => s2 + s1')
- ReturnedValue:
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 's2! => s2 + s1')
- Target:
- IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: 's2! => s2 + s1')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 's2 + s1')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 's2 + s1')
- ReturnedValue:
- IBinaryOperation (BinaryOperatorKind.Add) (OperationKind.Binary, Type: System.String) (Syntax: 's2 + s1')
- Left:
- IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's2')
- Right:
- IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's1')");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
- Left:
- IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s1"", IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Return) Block[B4]
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 's2! => s2 + s1')
- Target:
- IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: 's2! => s2 + s1')
- {
- Block[B0#A0] - Entry
- Statements (0)
- Next (Regular) Block[B1#A0]
- Block[B1#A0] - Block
- Predecessors: [B0#A0]
- Statements (0)
- Jump if False (Regular) to Block[B3#A0]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 's2! => s2 + s1')
- Left:
- IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 's2! => s2 + s1')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 's2! => s2 + s1')
- Next (Regular) Block[B2#A0]
- Block[B2#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 's2! => s2 + s1')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 's2! => s2 + s1')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s2"", IsImplicit) (Syntax: 's2! => s2 + s1')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Return) Block[B4#A0]
- IBinaryOperation (BinaryOperatorKind.Add) (OperationKind.Binary, Type: System.String) (Syntax: 's2 + s1')
- Left:
- IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's2')
- Right:
- IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's1')
- Block[B4#A0] - Exit
- Predecessors: [B3#A0]
- Statements (0)
- }
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedLambdaInField()
- {
- var source = @"
-using System;
-class C
-{
- Func func1 = x! => x;
- public C()
- {
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: 'x! => x')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
- ReturnedValue:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')");
-
- VerifyFlowGraph(compilation, node2, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: '= x! => x')
- Left:
- IFieldReferenceOperation: System.Func C.func1 (OperationKind.FieldReference, Type: System.Func, IsImplicit) (Syntax: '= x! => x')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: '= x! => x')
- Right:
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 'x! => x')
- Target:
- IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: 'x! => x')
- {
- Block[B0#A0] - Entry
- Statements (0)
- Next (Regular) Block[B1#A0]
- Block[B1#A0] - Block
- Predecessors: [B0#A0]
- Statements (0)
- Jump if False (Regular) to Block[B3#A0]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'x! => x')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'x! => x')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'x! => x')
- Next (Regular) Block[B2#A0]
- Block[B2#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'x! => x')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'x! => x')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'x! => x')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Return) Block[B4#A0]
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Block[B4#A0] - Exit
- Predecessors: [B3#A0]
- Statements (0)
- }
- Next (Regular) Block[B2]
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)
-");
- }
-
- [Fact]
- public void TestIOp_NullCheckedLocalFunction()
- {
- var source = @"
-class C
-{
- public void M()
- {
- InnerM(""hello world"");
- void InnerM(string x!) { }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- ILocalFunctionOperation (Symbol: void InnerM(System.String x)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ing x!) { }')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
- ReturnedValue:
- null");
- VerifyFlowGraph(compilation, node2, @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Methods: [void InnerM(System.String x)]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello world"");')
- Expression:
- IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello world"")')
- Instance Receiver:
- null
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello world""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello world"") (Syntax: '""hello world""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B2]
- Leaving: {R1}
-
- { void InnerM(System.String x)
-
- Block[B0#0R1] - Entry
- Statements (0)
- Next (Regular) Block[B1#0R1]
- Block[B1#0R1] - Block
- Predecessors: [B0#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B3#0R1]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Next (Regular) Block[B2#0R1]
- Block[B2#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#0R1] - Exit
- Predecessors: [B1#0R1]
- Statements (0)
- }
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedManyParamsInLocalFunction()
- {
- var source = @"
-class C
-{
- public void M()
- {
- InnerM(""hello"", ""world"");
- void InnerM(string x!, string y!) { }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- ILocalFunctionOperation (Symbol: void InnerM(System.String x, System.String y)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ing y!) { }')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
- ReturnedValue:
- null");
-
- VerifyFlowGraph(compilation, node2, @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Methods: [void InnerM(System.String x, System.String y)]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hel ... ""world"");')
- Expression:
- IInvocationOperation (void InnerM(System.String x, System.String y)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hel ... , ""world"")')
- Instance Receiver:
- null
- Arguments(2):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument, Type: null) (Syntax: '""world""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""world"") (Syntax: '""world""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B2]
- Leaving: {R1}
-
- { void InnerM(System.String x, System.String y)
-
- Block[B0#0R1] - Entry
- Statements (0)
- Next (Regular) Block[B1#0R1]
- Block[B1#0R1] - Block
- Predecessors: [B0#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B3#0R1]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Next (Regular) Block[B2#0R1]
- Block[B2#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B5#0R1]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Left:
- IParameterReferenceOperation: y (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Next (Regular) Block[B4#0R1]
- Block[B4#0R1] - Block
- Predecessors: [B3#0R1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""y"", IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B5#0R1] - Exit
- Predecessors: [B3#0R1]
- Statements (0)
- }
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_OuterNullCheckedShadowedParameter()
- {
- var source = @"
-class C
-{
- public void M(string x!)
- {
- InnerM(""hello"");
- void InnerM(string x) { }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
- BlockBody:
- IBlockOperation (2 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello"");')
- Expression:
- IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello"")')
- Instance Receiver:
- null
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- ILocalFunctionOperation (Symbol: void InnerM(System.String x)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ring x) { }')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
- ReturnedValue:
- null
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public void ... }')
- Entering: {R1}
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public void ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- .locals {R1}
- {
- Methods: [void InnerM(System.String x)]
- Block[B3] - Block
- Predecessors: [B1]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello"");')
- Expression:
- IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello"")')
- Instance Receiver:
- null
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B4]
- Leaving: {R1}
-
- { void InnerM(System.String x)
-
- Block[B0#0R1] - Entry
- Statements (0)
- Next (Regular) Block[B1#0R1]
- Block[B1#0R1] - Exit
- Predecessors: [B0#0R1]
- Statements (0)
- }
- }
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_InnerNullCheckedShadowedParameter()
- {
- var source = @"
-class C
-{
- public void M(string x)
- {
- InnerM(""hello"");
- void InnerM(string x!) { }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- ILocalFunctionOperation (Symbol: void InnerM(System.String x)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ing x!) { }')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
- ReturnedValue:
- null");
- VerifyFlowGraph(compilation, node2, @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Methods: [void InnerM(System.String x)]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello"");')
- Expression:
- IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello"")')
- Instance Receiver:
- null
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B2]
- Leaving: {R1}
-
- { void InnerM(System.String x)
-
- Block[B0#0R1] - Entry
- Statements (0)
- Next (Regular) Block[B1#0R1]
- Block[B1#0R1] - Block
- Predecessors: [B0#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B3#0R1]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Next (Regular) Block[B2#0R1]
- Block[B2#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3#0R1] - Exit
- Predecessors: [B1#0R1]
- Statements (0)
- }
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedConstructor()
- {
- var source = @"
-class C
-{
- public C(string x!) { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(string x!) { }')
- Initializer:
- null
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(string x!) { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(string x!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public C(string x!) { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(string x!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(string x!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(string x!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedConstructorWithThisChain()
- {
- var source = @"
-class C
-{
- public C() { }
- public C(string x!) : this() { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... this() { }')
- Initializer:
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': this()')
- Expression:
- IInvocationOperation ( C..ctor()) (OperationKind.Invocation, Type: System.Void) (Syntax: ': this()')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: ': this()')
- Arguments(0)
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... this() { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... this() { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public C(st ... this() { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... this() { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... this() { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(st ... this() { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': this()')
- Expression:
- IInvocationOperation ( C..ctor()) (OperationKind.Invocation, Type: System.Void) (Syntax: ': this()')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: ': this()')
- Arguments(0)
- Next (Regular) Block[B4]
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedConstructorWithBaseChain()
- {
- var source = @"
-class B
-{
- public B(string y) { }
-}
-class C : B
-{
- public C(string x!) : base(x) { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... base(x) { }')
- Initializer:
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(x)')
- Expression:
- IInvocationOperation ( B..ctor(System.String y)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(x)')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(x)')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument, Type: null) (Syntax: 'x')
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public C(st ... base(x) { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(st ... base(x) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(x)')
- Expression:
- IInvocationOperation ( B..ctor(System.String y)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(x)')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(x)')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument, Type: null) (Syntax: 'x')
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B4]
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedConstructorWithFieldInitializers()
- {
- var source = @"
-class C
-{
- int y = 5;
- public C(string x!) { y++; }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... !) { y++; }')
- Initializer:
- null
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ y++; }')
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'y++;')
- Expression:
- IIncrementOrDecrementOperation (Postfix) (OperationKind.Increment, Type: System.Int32) (Syntax: 'y++')
- Target:
- IFieldReferenceOperation: System.Int32 C.y (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'y')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'y')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'y++;')
- Expression:
- IIncrementOrDecrementOperation (Postfix) (OperationKind.Increment, Type: System.Int32) (Syntax: 'y++')
- Target:
- IFieldReferenceOperation: System.Int32 C.y (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'y')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'y')
- Next (Regular) Block[B4]
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedExpressionBodyMethod()
- {
- var source = @"
-class C
-{
- object Local(object arg!) => arg;
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'object Loca ... g!) => arg;')
- BlockBody:
- null
- ExpressionBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '=> arg')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'arg')
- ReturnedValue:
- IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'arg')");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
- Left:
- IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""arg"", IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Return) Block[B4]
- IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'arg')
- Block[B4] - Exit
- Predecessors: [B3]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedIterator()
- {
- var source = @"
-using System.Collections.Generic;
-class C
-{
- IEnumerable GetChars(string s!)
- {
- foreach (var c in s)
- {
- yield return c;
- }
- }
- public static void Main()
- {
- C c = new C();
- IEnumerable e = c.GetChars(""hello"");
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(0);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'IEnumerable ... }')
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IForEachLoopOperation (LoopKind.ForEach, Continue Label Id: 0, Exit Label Id: 1) (OperationKind.Loop, Type: null) (Syntax: 'foreach (va ... }')
- Locals: Local_1: System.Char c
- LoopControlVariable:
- IVariableDeclaratorOperation (Symbol: System.Char c) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'var')
- Initializer:
- null
- Collection:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
- Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Operand:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
- Body:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
- ReturnedValue:
- ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
- NextVariables(0)
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'IEnumerable ... }')
- Left:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'IEnumerable ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'IEnumerable ... }')
- Entering: {R1}
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'IEnumerable ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'IEnumerable ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'IEnumerable ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- .locals {R1}
- {
- CaptureIds: [0]
- Block[B3] - Block
- Predecessors: [B1]
- Statements (1)
- IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's')
- Value:
- IInvocationOperation ( System.CharEnumerator System.String.GetEnumerator()) (OperationKind.Invocation, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Instance Receiver:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
- Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- (Identity)
- Operand:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
- Arguments(0)
- Next (Regular) Block[B4]
- Entering: {R2} {R3}
- .try {R2, R3}
- {
- Block[B4] - Block
- Predecessors: [B3] [B5]
- Statements (0)
- Jump if False (Regular) to Block[B9]
- IInvocationOperation ( System.Boolean System.CharEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 's')
- Instance Receiver:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Arguments(0)
- Finalizing: {R5}
- Leaving: {R3} {R2} {R1}
- Next (Regular) Block[B5]
- Entering: {R4}
- .locals {R4}
- {
- Locals: [System.Char c]
- Block[B5] - Block
- Predecessors: [B4]
- Statements (2)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var')
- Left:
- ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Char, IsImplicit) (Syntax: 'var')
- Right:
- IPropertyReferenceOperation: System.Char System.CharEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Char, IsImplicit) (Syntax: 'var')
- Instance Receiver:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
- ReturnedValue:
- ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
- Next (Regular) Block[B4]
- Leaving: {R4}
- }
- }
- .finally {R5}
- {
- Block[B6] - Block
- Predecessors (0)
- Statements (0)
- Jump if True (Regular) to Block[B8]
- IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 's')
- Operand:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Next (Regular) Block[B7]
- Block[B7] - Block
- Predecessors: [B6]
- Statements (1)
- IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 's')
- Instance Receiver:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 's')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- (ImplicitReference)
- Operand:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Arguments(0)
- Next (Regular) Block[B8]
- Block[B8] - Block
- Predecessors: [B6] [B7]
- Statements (0)
- Next (StructuredExceptionHandling) Block[null]
- }
- }
- Block[B9] - Exit
- Predecessors: [B4]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedIteratorInLocalFunction()
- {
- var source = @"
-using System.Collections.Generic;
-class Iterators
-{
- void Use()
- {
- IEnumerable e = GetChars(""hello"");
- IEnumerable GetChars(string s!)
- {
- foreach (var c in s)
- {
- yield return c;
- }
- }
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- ILocalFunctionOperation (Symbol: System.Collections.Generic.IEnumerable GetChars(System.String s)) (OperationKind.LocalFunction, Type: null) (Syntax: 'IEnumerable ... }')
- IBlockOperation (2 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IForEachLoopOperation (LoopKind.ForEach, Continue Label Id: 0, Exit Label Id: 1) (OperationKind.Loop, Type: null) (Syntax: 'foreach (va ... }')
- Locals: Local_1: System.Char c
- LoopControlVariable:
- IVariableDeclaratorOperation (Symbol: System.Char c) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'var')
- Initializer:
- null
- Collection:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
- Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Operand:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
- Body:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
- ReturnedValue:
- ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
- NextVariables(0)
- IReturnOperation (OperationKind.YieldBreak, Type: null, IsImplicit) (Syntax: '{ ... }')
- ReturnedValue:
- null");
-
- VerifyFlowGraph(compilation, node2, @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Locals: [System.Collections.Generic.IEnumerable e]
- Methods: [System.Collections.Generic.IEnumerable GetChars(System.String s)]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Collections.Generic.IEnumerable, IsImplicit) (Syntax: 'e = GetChars(""hello"")')
- Left:
- ILocalReferenceOperation: e (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Collections.Generic.IEnumerable, IsImplicit) (Syntax: 'e = GetChars(""hello"")')
- Right:
- IInvocationOperation (System.Collections.Generic.IEnumerable GetChars(System.String s)) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerable) (Syntax: 'GetChars(""hello"")')
- Instance Receiver:
- null
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: s) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B2]
- Leaving: {R1}
-
- { System.Collections.Generic.IEnumerable GetChars(System.String s)
-
- Block[B0#0R1] - Entry
- Statements (0)
- Next (Regular) Block[B1#0R1]
- Block[B1#0R1] - Block
- Predecessors: [B0#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B3#0R1]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'IEnumerable ... }')
- Left:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'IEnumerable ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'IEnumerable ... }')
- Entering: {R1#0R1}
- Next (Regular) Block[B2#0R1]
- Block[B2#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'IEnumerable ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'IEnumerable ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'IEnumerable ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- .locals {R1#0R1}
- {
- CaptureIds: [0]
- Block[B3#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (1)
- IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's')
- Value:
- IInvocationOperation ( System.CharEnumerator System.String.GetEnumerator()) (OperationKind.Invocation, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Instance Receiver:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
- Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- (Identity)
- Operand:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
- Arguments(0)
- Next (Regular) Block[B4#0R1]
- Entering: {R2#0R1} {R3#0R1}
- .try {R2#0R1, R3#0R1}
- {
- Block[B4#0R1] - Block
- Predecessors: [B3#0R1] [B5#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B9#0R1]
- IInvocationOperation ( System.Boolean System.CharEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 's')
- Instance Receiver:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Arguments(0)
- Finalizing: {R5#0R1}
- Leaving: {R3#0R1} {R2#0R1} {R1#0R1}
- Next (Regular) Block[B5#0R1]
- Entering: {R4#0R1}
- .locals {R4#0R1}
- {
- Locals: [System.Char c]
- Block[B5#0R1] - Block
- Predecessors: [B4#0R1]
- Statements (2)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var')
- Left:
- ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Char, IsImplicit) (Syntax: 'var')
- Right:
- IPropertyReferenceOperation: System.Char System.CharEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Char, IsImplicit) (Syntax: 'var')
- Instance Receiver:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
- ReturnedValue:
- ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
- Next (Regular) Block[B4#0R1]
- Leaving: {R4#0R1}
- }
- }
- .finally {R5#0R1}
- {
- Block[B6#0R1] - Block
- Predecessors (0)
- Statements (0)
- Jump if True (Regular) to Block[B8#0R1]
- IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 's')
- Operand:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Next (Regular) Block[B7#0R1]
- Block[B7#0R1] - Block
- Predecessors: [B6#0R1]
- Statements (1)
- IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 's')
- Instance Receiver:
- IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 's')
- Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
- (ImplicitReference)
- Operand:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
- Arguments(0)
- Next (Regular) Block[B8#0R1]
- Block[B8#0R1] - Block
- Predecessors: [B6#0R1] [B7#0R1]
- Statements (0)
- Next (StructuredExceptionHandling) Block[null]
- }
- }
- Block[B9#0R1] - Exit
- Predecessors: [B4#0R1]
- Statements (0)
- }
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedEmptyIterator()
- {
- var source = @"
-using System.Collections.Generic;
-class C
-{
- public static void Main() { }
- static IEnumerable GetChars(string s!)
- {
- yield break;
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'static IEnu ... }')
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IReturnOperation (OperationKind.YieldBreak, Type: null) (Syntax: 'yield break;')
- ReturnedValue:
- null
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'static IEnu ... }')
- Left:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'static IEnu ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'static IEnu ... }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'static IEnu ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'static IEnu ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'static IEnu ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestIOp_NullCheckedEmptyIteratorReturningIEnumerator()
- {
- var source = @"
-using System.Collections.Generic;
-class C
-{
- public static void Main() { }
- static IEnumerator GetChars(string s!)
- {
- yield break;
- }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'static IEnu ... }')
- BlockBody:
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
- IReturnOperation (OperationKind.YieldBreak, Type: null) (Syntax: 'yield break;')
- ReturnedValue:
- null
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'static IEnu ... }')
- Left:
- IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'static IEnu ... }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'static IEnu ... }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'static IEnu ... }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'static IEnu ... }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'static IEnu ... }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestNullCheckedLambdaWithMissingType()
- {
- var source =
-@"
-using System;
-class Program
-{
- public static void Main()
- {
- Func func = x! => x;
- }
-}
-
-";
- var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
- comp.MakeMemberMissing(WellKnownMember.System_ArgumentNullException__ctorString);
- comp.MakeTypeMissing(WellKnownType.System_ArgumentNullException);
- comp.VerifyDiagnostics(
- // (7,37): error CS0656: Missing compiler required member 'System.ArgumentNullException..ctor'
- // Func func = x! => x;
- Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "x").WithArguments("System.ArgumentNullException", ".ctor").WithLocation(7, 37));
- var tree = comp.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- comp.VerifyOperationTree(node1, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null, IsInvalid) (Syntax: 'public stat ... }')
- BlockBody:
- IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null, IsInvalid) (Syntax: '{ ... }')
- Locals: Local_1: System.Func func
- IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null, IsInvalid) (Syntax: 'Func x;')
- IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null, IsInvalid) (Syntax: 'Func x')
- Declarators:
- IVariableDeclaratorOperation (Symbol: System.Func func) (OperationKind.VariableDeclarator, Type: null, IsInvalid) (Syntax: 'func = x! => x')
- Initializer:
- IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null, IsInvalid) (Syntax: '= x! => x')
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Target:
- IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null, IsInvalid) (Syntax: 'x! => x')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
- ReturnedValue:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Initializer:
- null
- ExpressionBody:
- null");
- VerifyFlowGraph(comp, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Locals: [System.Func func]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'func = x! => x')
- Left:
- ILocalReferenceOperation: func (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'func = x! => x')
- Right:
- IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Target:
- IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null, IsInvalid) (Syntax: 'x! => x')
- {
- Block[B0#A0] - Entry
- Statements (0)
- Next (Regular) Block[B1#A0]
- Block[B1#A0] - Block
- Predecessors: [B0#A0]
- Statements (0)
- Jump if False (Regular) to Block[B3#A0]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Next (Regular) Block[B2#A0]
- Block[B2#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Throw) Block[null]
- IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Children(1):
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsInvalid, IsImplicit) (Syntax: 'x! => x')
- Block[B3#A0] - Block
- Predecessors: [B1#A0]
- Statements (0)
- Next (Return) Block[B4#A0]
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
- Block[B4#A0] - Exit
- Predecessors: [B3#A0]
- Statements (0)
- }
- Next (Regular) Block[B2]
- Leaving: {R1}
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestNullCheckedLocalFunctionWithMissingType()
- {
- var source =
-@"
-class Program
-{
- public static void Main()
- {
- M(""ok"");
- void M(string x!) { }
- }
-}";
- var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
- comp.MakeMemberMissing(WellKnownMember.System_ArgumentNullException__ctorString);
- comp.MakeTypeMissing(WellKnownType.System_ArgumentNullException);
- comp.VerifyDiagnostics(
- // (7,23): error CS0656: Missing compiler required member 'System.ArgumentNullException..ctor'
- // void M(string x!) { }
- Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "x").WithArguments("System.ArgumentNullException", ".ctor").WithLocation(7, 23));
- var tree = comp.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
- var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
- comp.VerifyOperationTree(node1, expectedOperationTree: @"
- ILocalFunctionOperation (Symbol: void M(System.String x)) (OperationKind.LocalFunction, Type: null, IsInvalid) (Syntax: 'void M(string x!) { }')
- IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
- ReturnedValue:
- null");
- VerifyFlowGraph(comp, node2, @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Entering: {R1}
- .locals {R1}
- {
- Methods: [void M(System.String x)]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'M(""ok"");')
- Expression:
- IInvocationOperation (void M(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'M(""ok"")')
- Instance Receiver:
- null
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""ok""')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""ok"") (Syntax: '""ok""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B2]
- Leaving: {R1}
-
- { void M(System.String x)
-
- Block[B0#0R1] - Entry
- Statements (0)
- Next (Regular) Block[B1#0R1]
- Block[B1#0R1] - Block
- Predecessors: [B0#0R1]
- Statements (0)
- Jump if False (Regular) to Block[B3#0R1]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
- Left:
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
- Next (Regular) Block[B2#0R1]
- Block[B2#0R1] - Block
- Predecessors: [B1#0R1]
- Statements (0)
- Next (Throw) Block[null]
- IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
- Children(1):
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
- Block[B3#0R1] - Exit
- Predecessors: [B1#0R1]
- Statements (0)
- }
- }
- Block[B2] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact]
- public void TestNullCheckedMethodWithMissingHasValue()
- {
- var source =
-@"
-class Program
-{
- public void Method(int? x!) { }
-}";
- var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
- comp.MakeMemberMissing(SpecialMember.System_Nullable_T_get_HasValue);
- comp.VerifyDiagnostics(
- // (4,29): warning CS8721: Nullable value type 'int?' is null-checked and will throw if null.
- // public void Method(int? x!) { }
- Diagnostic(ErrorCode.WRN_NullCheckingOnNullableValueType, "x").WithArguments("int?").WithLocation(4, 29));
- var tree = comp.SyntaxTrees.Single();
- var node = tree.GetRoot().DescendantNodes().OfType().Single();
- comp.VerifyOperationTree(node, expectedOperationTree: @"
- IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... nt? x!) { }')
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
- VerifyFlowGraph(comp, node, @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if True (Regular) to Block[B3]
- IInvalidOperation (OperationKind.Invalid, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
- Children(1):
- IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32?, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public void ... nt? x!) { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- Block[B3] - Exit
- Predecessors: [B1]
- Statements (0)");
- }
-
- [Fact(Skip = "PROTOTYPE")]
- public void TestNoNullChecksInBlockOperation()
- {
- // PROTOTYPE - Nullchecks currently included when only BlockSyntax is bound. Falls into VisitMethodBody instead of VisitBlock.
- var source = @"
-public class C
-{
- public void M(string input!)
- /**/{ }/* */
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
-
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
-IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
-");
- var output = @"";
- VerifyFlowGraphAndDiagnosticsForTest(compilation, expectedFlowGraph: output, DiagnosticDescription.None);
- }
-
- [Fact]
- public void TestNullCheckedBaseCallOrdering()
- {
- var source = @"
-public class B
-{
- public B(string x) { }
-}
-public class C : B
-{
- public C(string param!) : base(param ?? """") { }
-}";
- var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
-
- compilation.VerifyDiagnostics();
-
- var tree = compilation.SyntaxTrees.Single();
- var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
- compilation.VerifyOperationTree(node1, expectedOperationTree: @"
- IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... ?? """") { }')
- Initializer:
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(param ?? """")')
- Expression:
- IInvocationOperation ( B..ctor(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(param ?? """")')
- Instance Receiver:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(param ?? """")')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: 'param ?? """"')
- ICoalesceOperation (OperationKind.Coalesce, Type: System.String) (Syntax: 'param ?? """"')
- Expression:
- IParameterReferenceOperation: param (OperationKind.ParameterReference, Type: System.String) (Syntax: 'param')
- ValueConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- (Identity)
- WhenNull:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- BlockBody:
- IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
- ExpressionBody:
- null");
-
- VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
- Block[B0] - Entry
- Statements (0)
- Next (Regular) Block[B1]
- Block[B1] - Block
- Predecessors: [B0]
- Statements (0)
- Jump if False (Regular) to Block[B3]
- IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
- Left:
- IParameterReferenceOperation: param (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
- Right:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ConstantValueNull(null: Null), IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
- Entering: {R1}
- Next (Regular) Block[B2]
- Block[B2] - Block
- Predecessors: [B1]
- Statements (0)
- Next (Throw) Block[null]
- IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""param"", IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Initializer:
- null
- .locals {R1}
- {
- CaptureIds: [0] [2]
- Block[B3] - Block
- Predecessors: [B1]
- Statements (1)
- IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: ': base(param ?? """")')
- Value:
- IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(param ?? """")')
- Next (Regular) Block[B4]
- Entering: {R2}
- .locals {R2}
- {
- CaptureIds: [1]
- Block[B4] - Block
- Predecessors: [B3]
- Statements (1)
- IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'param')
- Value:
- IParameterReferenceOperation: param (OperationKind.ParameterReference, Type: System.String) (Syntax: 'param')
- Jump if True (Regular) to Block[B6]
- IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'param')
- Operand:
- IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'param')
- Leaving: {R2}
- Next (Regular) Block[B5]
- Block[B5] - Block
- Predecessors: [B4]
- Statements (1)
- IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'param')
- Value:
- IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'param')
- Next (Regular) Block[B7]
- Leaving: {R2}
- }
- Block[B6] - Block
- Predecessors: [B4]
- Statements (1)
- IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '""""')
- Value:
- ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
- Next (Regular) Block[B7]
- Block[B7] - Block
- Predecessors: [B5] [B6]
- Statements (1)
- IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(param ?? """")')
- Expression:
- IInvocationOperation ( B..ctor(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(param ?? """")')
- Instance Receiver:
- IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: B, IsImplicit) (Syntax: ': base(param ?? """")')
- Arguments(1):
- IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: 'param ?? """"')
- IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'param ?? """"')
- InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
- Next (Regular) Block[B8]
- Leaving: {R1}
- }
- Block[B8] - Exit
- Predecessors: [B7]
- Statements (0)");
- }
- }
-}
diff --git a/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_INullCheckedParameters.cs b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_INullCheckedParameters.cs
new file mode 100644
index 0000000000000..49ffbeb216160
--- /dev/null
+++ b/src/Compilers/CSharp/Test/IOperation/IOperation/IOperationTests_INullCheckedParameters.cs
@@ -0,0 +1,2647 @@
+// 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.Linq;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
+using Microsoft.CodeAnalysis.FlowAnalysis;
+using Microsoft.CodeAnalysis.Operations;
+using Microsoft.CodeAnalysis.Test.Utilities;
+using Xunit;
+
+namespace Microsoft.CodeAnalysis.CSharp.UnitTests
+{
+ public partial class IOperationTests : SemanticModelTestBase
+ {
+ [CompilerTrait(CompilerFeature.IOperation, CompilerFeature.Dataflow)]
+ [Fact]
+ public void NullCheckedMethodDeclarationIOp()
+ {
+ var source = @"
+public class C
+{
+ public void M(string input!) { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... input!) { }')
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... input!) { }')
+ Left:
+ IParameterReferenceOperation: input (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... input!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public void ... input!) { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... input!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... input!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""input"", IsImplicit) (Syntax: 'public void ... input!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_OneNullCheckedManyParams()
+ {
+ var source = @"
+public class C
+{
+ public void M(string x, string y!) { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... ing y!) { }')
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... ing y!) { }')
+ Left:
+ IParameterReferenceOperation: y (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... ing y!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public void ... ing y!) { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... ing y!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... ing y!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""y"", IsImplicit) (Syntax: 'public void ... ing y!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_OneNullCheckedParamWithStringOpt()
+ {
+ var source = @"
+public class C
+{
+ public void M(string name! = ""rose"") { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... ""rose"") { }')
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
+ Left:
+ IParameterReferenceOperation: name (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... ""rose"") { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""name"", IsImplicit) (Syntax: 'public void ... ""rose"") { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedOperator()
+ {
+ var source = @"
+public class Box
+{
+ public static int operator+ (Box b!, Box c)
+ {
+ return 2;
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public stat ... }')
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IReturnOperation (OperationKind.Return, Type: null) (Syntax: 'return 2;')
+ ReturnedValue:
+ ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public stat ... }')
+ Left:
+ IParameterReferenceOperation: b (OperationKind.ParameterReference, Type: Box, IsImplicit) (Syntax: 'public stat ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: Box, Constant: null, IsImplicit) (Syntax: 'public stat ... }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public stat ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public stat ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""b"", IsImplicit) (Syntax: 'public stat ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Return) Block[B4]
+ ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 2) (Syntax: '2')
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedIndexedProperty()
+ {
+ // PROTOTYPE
+ var source = @"
+public class C
+{
+ public string this[string index!] => null;
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '=> null')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'null')
+ ReturnedValue:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ Operand:
+ ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Next (Return) Block[B2]
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ (ImplicitReference)
+ Operand:
+ ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedIndexedGetterSetter()
+ {
+ var source = @"
+public class C
+{
+ private object[] items = {'h', ""hello""};
+ public string this[object item!]
+ {
+ /**/get
+ {
+ return items[0].ToString();
+ }/* */
+ set
+ {
+ items[0] = value;
+ }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'set ... }')
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'items[0] = value;')
+ Expression:
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Object) (Syntax: 'items[0] = value')
+ Left:
+ IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
+ Array reference:
+ IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
+ Indices(1):
+ ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
+ Right:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'value')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ Operand:
+ IParameterReferenceOperation: value (OperationKind.ParameterReference, Type: System.String) (Syntax: 'value')
+ ExpressionBody:
+ null");
+ var expected = @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'get ... }')
+ Left:
+ IParameterReferenceOperation: item (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'get ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: null, IsImplicit) (Syntax: 'get ... }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'get ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'get ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""item"", IsImplicit) (Syntax: 'get ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Return) Block[B4]
+ IInvocationOperation (virtual System.String System.Object.ToString()) (OperationKind.Invocation, Type: System.String) (Syntax: 'items[0].ToString()')
+ Instance Receiver:
+ IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
+ Array reference:
+ IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
+ Indices(1):
+ ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
+ Arguments(0)
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)";
+ VerifyFlowGraphAndDiagnosticsForTest(source, expected, DiagnosticDescription.None, parseOptions: TestOptions.RegularPreview);
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedIndexedGetterExpression()
+ {
+ var source = @"
+public class C
+{
+ private object[] items = {'h', ""hello""};
+ public string this[object item!]
+ {
+ /**/get => items[0].ToString();/* */
+ set
+ {
+ items[0] = value;
+ }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'set ... }')
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'items[0] = value;')
+ Expression:
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Object) (Syntax: 'items[0] = value')
+ Left:
+ IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
+ Array reference:
+ IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
+ Indices(1):
+ ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
+ Right:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.Object, IsImplicit) (Syntax: 'value')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ Operand:
+ IParameterReferenceOperation: value (OperationKind.ParameterReference, Type: System.String) (Syntax: 'value')
+ ExpressionBody:
+ null");
+ var expected = @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'get => item ... ToString();')
+ Left:
+ IParameterReferenceOperation: item (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'get => item ... ToString();')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: null, IsImplicit) (Syntax: 'get => item ... ToString();')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'get => item ... ToString();')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'get => item ... ToString();')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""item"", IsImplicit) (Syntax: 'get => item ... ToString();')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Return) Block[B4]
+ IInvocationOperation (virtual System.String System.Object.ToString()) (OperationKind.Invocation, Type: System.String) (Syntax: 'items[0].ToString()')
+ Instance Receiver:
+ IArrayElementReferenceOperation (OperationKind.ArrayElementReference, Type: System.Object) (Syntax: 'items[0]')
+ Array reference:
+ IFieldReferenceOperation: System.Object[] C.items (OperationKind.FieldReference, Type: System.Object[]) (Syntax: 'items')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'items')
+ Indices(1):
+ ILiteralOperation (OperationKind.Literal, Type: System.Int32, Constant: 0) (Syntax: '0')
+ Arguments(0)
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)";
+
+ VerifyFlowGraphAndDiagnosticsForTest(source, expected, DiagnosticDescription.None, parseOptions: TestOptions.RegularPreview);
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedIndexedSetter()
+ {
+ var source = @"
+public class C
+{
+ public string this[object item!] { /**/set { }/* */ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'set { }')
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+ var expected = @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'set { }')
+ Left:
+ IParameterReferenceOperation: item (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'set { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: null, IsImplicit) (Syntax: 'set { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'set { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'set { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""item"", IsImplicit) (Syntax: 'set { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)";
+ VerifyFlowGraphAndDiagnosticsForTest(source, expected, DiagnosticDescription.None, parseOptions: TestOptions.RegularPreview);
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedLambda()
+ {
+ var source = @"
+using System;
+class C
+{
+ public void M()
+ {
+ Func func1 = x! => x;
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
+ BlockBody:
+ IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ Locals: Local_1: System.Func func1
+ IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'Func x;')
+ IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'Func x')
+ Declarators:
+ IVariableDeclaratorOperation (Symbol: System.Func func1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'func1 = x! => x')
+ Initializer:
+ IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= x! => x')
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 'x! => x')
+ Target:
+ IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: 'x! => x')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
+ ReturnedValue:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Initializer:
+ null
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Locals: [System.Func func1]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: 'func1 = x! => x')
+ Left:
+ ILocalReferenceOperation: func1 (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsImplicit) (Syntax: 'func1 = x! => x')
+ Right:
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 'x! => x')
+ Target:
+ IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: 'x! => x')
+ {
+ Block[B0#A0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#A0]
+ Block[B1#A0] - Block
+ Predecessors: [B0#A0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#A0]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'x! => x')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'x! => x')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'x! => x')
+ Next (Regular) Block[B2#A0]
+ Block[B2#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'x! => x')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'x! => x')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'x! => x')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Return) Block[B4#A0]
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Block[B4#A0] - Exit
+ Predecessors: [B3#A0]
+ Statements (0)
+ }
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedInLambdaWithManyParameters()
+ {
+ var source = @"
+using System;
+class C
+{
+ public void M()
+ {
+ Func func1 = (x!, y) => x;
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
+ BlockBody:
+ IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ Locals: Local_1: System.Func func1
+ IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'Func x;')
+ IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'Func x')
+ Declarators:
+ IVariableDeclaratorOperation (Symbol: System.Func func1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'func1 = (x!, y) => x')
+ Initializer:
+ IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= (x!, y) => x')
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '(x!, y) => x')
+ Target:
+ IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: '(x!, y) => x')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
+ ReturnedValue:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Initializer:
+ null
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Locals: [System.Func func1]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: 'func1 = (x!, y) => x')
+ Left:
+ ILocalReferenceOperation: func1 (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsImplicit) (Syntax: 'func1 = (x!, y) => x')
+ Right:
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '(x!, y) => x')
+ Target:
+ IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: '(x!, y) => x')
+ {
+ Block[B0#A0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#A0]
+ Block[B1#A0] - Block
+ Predecessors: [B0#A0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#A0]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: '(x!, y) => x')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: '(x!, y) => x')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: '(x!, y) => x')
+ Next (Regular) Block[B2#A0]
+ Block[B2#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: '(x!, y) => x')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: '(x!, y) => x')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: '(x!, y) => x')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Return) Block[B4#A0]
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Block[B4#A0] - Exit
+ Predecessors: [B3#A0]
+ Statements (0)
+ }
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedUnnamedVariableInLambda()
+ {
+ var source = @"
+using System;
+class C
+{
+ public void M()
+ {
+ Func func1 = _! => null;
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
+ BlockBody:
+ IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ Locals: Local_1: System.Func func1
+ IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'Func null;')
+ IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'Func null')
+ Declarators:
+ IVariableDeclaratorOperation (Symbol: System.Func func1) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'func1 = _! => null')
+ Initializer:
+ IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= _! => null')
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '_! => null')
+ Target:
+ IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: '_! => null')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'null')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'null')
+ ReturnedValue:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ Operand:
+ ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')
+ Initializer:
+ null
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Locals: [System.Func func1]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: 'func1 = _! => null')
+ Left:
+ ILocalReferenceOperation: func1 (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsImplicit) (Syntax: 'func1 = _! => null')
+ Right:
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: '_! => null')
+ Target:
+ IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: '_! => null')
+ {
+ Block[B0#A0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#A0]
+ Block[B1#A0] - Block
+ Predecessors: [B0#A0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#A0]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: '_! => null')
+ Left:
+ IParameterReferenceOperation: _ (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: '_! => null')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: '_! => null')
+ Next (Regular) Block[B2#A0]
+ Block[B2#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: '_! => null')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: '_! => null')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""_"", IsImplicit) (Syntax: '_! => null')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Return) Block[B4#A0]
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, Constant: null, IsImplicit) (Syntax: 'null')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ (ImplicitReference)
+ Operand:
+ ILiteralOperation (OperationKind.Literal, Type: null, Constant: null) (Syntax: 'null')
+ Block[B4#A0] - Exit
+ Predecessors: [B3#A0]
+ Statements (0)
+ }
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedTwoExpressionBodyLambdas()
+ {
+ var source = @"
+using System;
+class C
+{
+ public Func M(string s1!) => s2! => s2 + s1;
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public Func ... => s2 + s1;')
+ BlockBody:
+ null
+ ExpressionBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '=> s2! => s2 + s1')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 's2! => s2 + s1')
+ ReturnedValue:
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 's2! => s2 + s1')
+ Target:
+ IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: 's2! => s2 + s1')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 's2 + s1')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 's2 + s1')
+ ReturnedValue:
+ IBinaryOperation (BinaryOperatorKind.Add) (OperationKind.Binary, Type: System.String) (Syntax: 's2 + s1')
+ Left:
+ IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's2')
+ Right:
+ IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's1')");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
+ Left:
+ IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s1"", IsImplicit) (Syntax: 'public Func ... => s2 + s1;')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Return) Block[B4]
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 's2! => s2 + s1')
+ Target:
+ IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: 's2! => s2 + s1')
+ {
+ Block[B0#A0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#A0]
+ Block[B1#A0] - Block
+ Predecessors: [B0#A0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#A0]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 's2! => s2 + s1')
+ Left:
+ IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 's2! => s2 + s1')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 's2! => s2 + s1')
+ Next (Regular) Block[B2#A0]
+ Block[B2#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 's2! => s2 + s1')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 's2! => s2 + s1')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s2"", IsImplicit) (Syntax: 's2! => s2 + s1')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Return) Block[B4#A0]
+ IBinaryOperation (BinaryOperatorKind.Add) (OperationKind.Binary, Type: System.String) (Syntax: 's2 + s1')
+ Left:
+ IParameterReferenceOperation: s2 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's2')
+ Right:
+ IParameterReferenceOperation: s1 (OperationKind.ParameterReference, Type: System.String) (Syntax: 's1')
+ Block[B4#A0] - Exit
+ Predecessors: [B3#A0]
+ Statements (0)
+ }
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedLambdaInField()
+ {
+ var source = @"
+using System;
+class C
+{
+ Func func1 = x! => x;
+ public C()
+ {
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null) (Syntax: 'x! => x')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
+ ReturnedValue:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')");
+
+ VerifyFlowGraph(compilation, node2, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsImplicit) (Syntax: '= x! => x')
+ Left:
+ IFieldReferenceOperation: System.Func C.func1 (OperationKind.FieldReference, Type: System.Func, IsImplicit) (Syntax: '= x! => x')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: '= x! => x')
+ Right:
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsImplicit) (Syntax: 'x! => x')
+ Target:
+ IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null) (Syntax: 'x! => x')
+ {
+ Block[B0#A0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#A0]
+ Block[B1#A0] - Block
+ Predecessors: [B0#A0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#A0]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'x! => x')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'x! => x')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'x! => x')
+ Next (Regular) Block[B2#A0]
+ Block[B2#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'x! => x')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'x! => x')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'x! => x')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Return) Block[B4#A0]
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Block[B4#A0] - Exit
+ Predecessors: [B3#A0]
+ Statements (0)
+ }
+ Next (Regular) Block[B2]
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)
+");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedLocalFunction()
+ {
+ var source = @"
+class C
+{
+ public void M()
+ {
+ InnerM(""hello world"");
+ void InnerM(string x!) { }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ ILocalFunctionOperation (Symbol: void InnerM(System.String x)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ing x!) { }')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
+ ReturnedValue:
+ null");
+ VerifyFlowGraph(compilation, node2, @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Methods: [void InnerM(System.String x)]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello world"");')
+ Expression:
+ IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello world"")')
+ Instance Receiver:
+ null
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello world""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello world"") (Syntax: '""hello world""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+
+ { void InnerM(System.String x)
+
+ Block[B0#0R1] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#0R1]
+ Block[B1#0R1] - Block
+ Predecessors: [B0#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#0R1]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Next (Regular) Block[B2#0R1]
+ Block[B2#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#0R1] - Exit
+ Predecessors: [B1#0R1]
+ Statements (0)
+ }
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedManyParamsInLocalFunction()
+ {
+ var source = @"
+class C
+{
+ public void M()
+ {
+ InnerM(""hello"", ""world"");
+ void InnerM(string x!, string y!) { }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ ILocalFunctionOperation (Symbol: void InnerM(System.String x, System.String y)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ing y!) { }')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
+ ReturnedValue:
+ null");
+
+ VerifyFlowGraph(compilation, node2, @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Methods: [void InnerM(System.String x, System.String y)]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hel ... ""world"");')
+ Expression:
+ IInvocationOperation (void InnerM(System.String x, System.String y)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hel ... , ""world"")')
+ Instance Receiver:
+ null
+ Arguments(2):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument, Type: null) (Syntax: '""world""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""world"") (Syntax: '""world""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+
+ { void InnerM(System.String x, System.String y)
+
+ Block[B0#0R1] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#0R1]
+ Block[B1#0R1] - Block
+ Predecessors: [B0#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#0R1]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Next (Regular) Block[B2#0R1]
+ Block[B2#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B5#0R1]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Left:
+ IParameterReferenceOperation: y (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Next (Regular) Block[B4#0R1]
+ Block[B4#0R1] - Block
+ Predecessors: [B3#0R1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""y"", IsImplicit) (Syntax: 'void InnerM ... ing y!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B5#0R1] - Exit
+ Predecessors: [B3#0R1]
+ Statements (0)
+ }
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_OuterNullCheckedShadowedParameter()
+ {
+ var source = @"
+class C
+{
+ public void M(string x!)
+ {
+ InnerM(""hello"");
+ void InnerM(string x) { }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... }')
+ BlockBody:
+ IBlockOperation (2 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello"");')
+ Expression:
+ IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello"")')
+ Instance Receiver:
+ null
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ ILocalFunctionOperation (Symbol: void InnerM(System.String x)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ring x) { }')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
+ ReturnedValue:
+ null
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public void ... }')
+ Entering: {R1}
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public void ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+.locals {R1}
+{
+ Methods: [void InnerM(System.String x)]
+ Block[B3] - Block
+ Predecessors: [B1]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello"");')
+ Expression:
+ IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello"")')
+ Instance Receiver:
+ null
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B4]
+ Leaving: {R1}
+
+ { void InnerM(System.String x)
+
+ Block[B0#0R1] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#0R1]
+ Block[B1#0R1] - Exit
+ Predecessors: [B0#0R1]
+ Statements (0)
+ }
+}
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_InnerNullCheckedShadowedParameter()
+ {
+ var source = @"
+class C
+{
+ public void M(string x)
+ {
+ InnerM(""hello"");
+ void InnerM(string x!) { }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ ILocalFunctionOperation (Symbol: void InnerM(System.String x)) (OperationKind.LocalFunction, Type: null) (Syntax: 'void InnerM ... ing x!) { }')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
+ ReturnedValue:
+ null");
+ VerifyFlowGraph(compilation, node2, @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Methods: [void InnerM(System.String x)]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'InnerM(""hello"");')
+ Expression:
+ IInvocationOperation (void InnerM(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'InnerM(""hello"")')
+ Instance Receiver:
+ null
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+
+ { void InnerM(System.String x)
+
+ Block[B0#0R1] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#0R1]
+ Block[B1#0R1] - Block
+ Predecessors: [B0#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#0R1]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Next (Regular) Block[B2#0R1]
+ Block[B2#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'void InnerM ... ing x!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3#0R1] - Exit
+ Predecessors: [B1#0R1]
+ Statements (0)
+ }
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedConstructor()
+ {
+ var source = @"
+class C
+{
+ public C(string x!) { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(string x!) { }')
+ Initializer:
+ null
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(string x!) { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(string x!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public C(string x!) { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(string x!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(string x!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(string x!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedConstructorWithThisChain()
+ {
+ var source = @"
+class C
+{
+ public C() { }
+ public C(string x!) : this() { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... this() { }')
+ Initializer:
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': this()')
+ Expression:
+ IInvocationOperation ( C..ctor()) (OperationKind.Invocation, Type: System.Void) (Syntax: ': this()')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: ': this()')
+ Arguments(0)
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... this() { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... this() { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public C(st ... this() { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... this() { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... this() { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(st ... this() { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': this()')
+ Expression:
+ IInvocationOperation ( C..ctor()) (OperationKind.Invocation, Type: System.Void) (Syntax: ': this()')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: ': this()')
+ Arguments(0)
+ Next (Regular) Block[B4]
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedConstructorWithBaseChain()
+ {
+ var source = @"
+class B
+{
+ public B(string y) { }
+}
+class C : B
+{
+ public C(string x!) : base(x) { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... base(x) { }')
+ Initializer:
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(x)')
+ Expression:
+ IInvocationOperation ( B..ctor(System.String y)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(x)')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(x)')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument, Type: null) (Syntax: 'x')
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... base(x) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(st ... base(x) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(x)')
+ Expression:
+ IInvocationOperation ( B..ctor(System.String y)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(x)')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(x)')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument, Type: null) (Syntax: 'x')
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B4]
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedConstructorWithFieldInitializers()
+ {
+ var source = @"
+class C
+{
+ int y = 5;
+ public C(string x!) { y++; }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... !) { y++; }')
+ Initializer:
+ null
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ y++; }')
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'y++;')
+ Expression:
+ IIncrementOrDecrementOperation (Postfix) (OperationKind.Increment, Type: System.Int32) (Syntax: 'y++')
+ Target:
+ IFieldReferenceOperation: System.Int32 C.y (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'y')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'y')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public C(st ... !) { y++; }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'y++;')
+ Expression:
+ IIncrementOrDecrementOperation (Postfix) (OperationKind.Increment, Type: System.Int32) (Syntax: 'y++')
+ Target:
+ IFieldReferenceOperation: System.Int32 C.y (OperationKind.FieldReference, Type: System.Int32) (Syntax: 'y')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: C, IsImplicit) (Syntax: 'y')
+ Next (Regular) Block[B4]
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedExpressionBodyMethod()
+ {
+ var source = @"
+class C
+{
+ object Local(object arg!) => arg;
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'object Loca ... g!) => arg;')
+ BlockBody:
+ null
+ ExpressionBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '=> arg')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'arg')
+ ReturnedValue:
+ IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'arg')");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
+ Left:
+ IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Object, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.Object, Constant: null, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""arg"", IsImplicit) (Syntax: 'object Loca ... g!) => arg;')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Return) Block[B4]
+ IParameterReferenceOperation: arg (OperationKind.ParameterReference, Type: System.Object) (Syntax: 'arg')
+Block[B4] - Exit
+ Predecessors: [B3]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedIterator()
+ {
+ var source = @"
+using System.Collections.Generic;
+class C
+{
+ IEnumerable GetChars(string s!)
+ {
+ foreach (var c in s)
+ {
+ yield return c;
+ }
+ }
+ public static void Main()
+ {
+ C c = new C();
+ IEnumerable e = c.GetChars(""hello"");
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(0);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'IEnumerable ... }')
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IForEachLoopOperation (LoopKind.ForEach, Continue Label Id: 0, Exit Label Id: 1) (OperationKind.Loop, Type: null) (Syntax: 'foreach (va ... }')
+ Locals: Local_1: System.Char c
+ LoopControlVariable:
+ IVariableDeclaratorOperation (Symbol: System.Char c) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'var')
+ Initializer:
+ null
+ Collection:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
+ Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Operand:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
+ Body:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
+ ReturnedValue:
+ ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
+ NextVariables(0)
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Left:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Entering: {R1}
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'IEnumerable ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'IEnumerable ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+.locals {R1}
+{
+ CaptureIds: [0]
+ Block[B3] - Block
+ Predecessors: [B1]
+ Statements (1)
+ IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's')
+ Value:
+ IInvocationOperation ( System.CharEnumerator System.String.GetEnumerator()) (OperationKind.Invocation, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Instance Receiver:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
+ Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ (Identity)
+ Operand:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
+ Arguments(0)
+ Next (Regular) Block[B4]
+ Entering: {R2} {R3}
+ .try {R2, R3}
+ {
+ Block[B4] - Block
+ Predecessors: [B3] [B5]
+ Statements (0)
+ Jump if False (Regular) to Block[B9]
+ IInvocationOperation ( System.Boolean System.CharEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 's')
+ Instance Receiver:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Arguments(0)
+ Finalizing: {R5}
+ Leaving: {R3} {R2} {R1}
+ Next (Regular) Block[B5]
+ Entering: {R4}
+ .locals {R4}
+ {
+ Locals: [System.Char c]
+ Block[B5] - Block
+ Predecessors: [B4]
+ Statements (2)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var')
+ Left:
+ ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Char, IsImplicit) (Syntax: 'var')
+ Right:
+ IPropertyReferenceOperation: System.Char System.CharEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Char, IsImplicit) (Syntax: 'var')
+ Instance Receiver:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
+ ReturnedValue:
+ ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
+ Next (Regular) Block[B4]
+ Leaving: {R4}
+ }
+ }
+ .finally {R5}
+ {
+ Block[B6] - Block
+ Predecessors (0)
+ Statements (0)
+ Jump if True (Regular) to Block[B8]
+ IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 's')
+ Operand:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Next (Regular) Block[B7]
+ Block[B7] - Block
+ Predecessors: [B6]
+ Statements (1)
+ IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 's')
+ Instance Receiver:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 's')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ (ImplicitReference)
+ Operand:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Arguments(0)
+ Next (Regular) Block[B8]
+ Block[B8] - Block
+ Predecessors: [B6] [B7]
+ Statements (0)
+ Next (StructuredExceptionHandling) Block[null]
+ }
+}
+Block[B9] - Exit
+ Predecessors: [B4]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedIteratorInLocalFunction()
+ {
+ var source = @"
+using System.Collections.Generic;
+class Iterators
+{
+ void Use()
+ {
+ IEnumerable e = GetChars(""hello"");
+ IEnumerable GetChars(string s!)
+ {
+ foreach (var c in s)
+ {
+ yield return c;
+ }
+ }
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ ILocalFunctionOperation (Symbol: System.Collections.Generic.IEnumerable GetChars(System.String s)) (OperationKind.LocalFunction, Type: null) (Syntax: 'IEnumerable ... }')
+ IBlockOperation (2 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IForEachLoopOperation (LoopKind.ForEach, Continue Label Id: 0, Exit Label Id: 1) (OperationKind.Loop, Type: null) (Syntax: 'foreach (va ... }')
+ Locals: Local_1: System.Char c
+ LoopControlVariable:
+ IVariableDeclaratorOperation (Symbol: System.Char c) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'var')
+ Initializer:
+ null
+ Collection:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
+ Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Operand:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
+ Body:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
+ ReturnedValue:
+ ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
+ NextVariables(0)
+ IReturnOperation (OperationKind.YieldBreak, Type: null, IsImplicit) (Syntax: '{ ... }')
+ ReturnedValue:
+ null");
+
+ VerifyFlowGraph(compilation, node2, @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Locals: [System.Collections.Generic.IEnumerable e]
+ Methods: [System.Collections.Generic.IEnumerable GetChars(System.String s)]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Collections.Generic.IEnumerable, IsImplicit) (Syntax: 'e = GetChars(""hello"")')
+ Left:
+ ILocalReferenceOperation: e (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Collections.Generic.IEnumerable, IsImplicit) (Syntax: 'e = GetChars(""hello"")')
+ Right:
+ IInvocationOperation (System.Collections.Generic.IEnumerable GetChars(System.String s)) (OperationKind.Invocation, Type: System.Collections.Generic.IEnumerable) (Syntax: 'GetChars(""hello"")')
+ Instance Receiver:
+ null
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: s) (OperationKind.Argument, Type: null) (Syntax: '""hello""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""hello"") (Syntax: '""hello""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+
+ { System.Collections.Generic.IEnumerable GetChars(System.String s)
+
+ Block[B0#0R1] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#0R1]
+ Block[B1#0R1] - Block
+ Predecessors: [B0#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#0R1]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Left:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Entering: {R1#0R1}
+ Next (Regular) Block[B2#0R1]
+ Block[B2#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'IEnumerable ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'IEnumerable ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'IEnumerable ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ .locals {R1#0R1}
+ {
+ CaptureIds: [0]
+ Block[B3#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (1)
+ IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 's')
+ Value:
+ IInvocationOperation ( System.CharEnumerator System.String.GetEnumerator()) (OperationKind.Invocation, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Instance Receiver:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.String, IsImplicit) (Syntax: 's')
+ Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ (Identity)
+ Operand:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String) (Syntax: 's')
+ Arguments(0)
+ Next (Regular) Block[B4#0R1]
+ Entering: {R2#0R1} {R3#0R1}
+ .try {R2#0R1, R3#0R1}
+ {
+ Block[B4#0R1] - Block
+ Predecessors: [B3#0R1] [B5#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B9#0R1]
+ IInvocationOperation ( System.Boolean System.CharEnumerator.MoveNext()) (OperationKind.Invocation, Type: System.Boolean, IsImplicit) (Syntax: 's')
+ Instance Receiver:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Arguments(0)
+ Finalizing: {R5#0R1}
+ Leaving: {R3#0R1} {R2#0R1} {R1#0R1}
+ Next (Regular) Block[B5#0R1]
+ Entering: {R4#0R1}
+ .locals {R4#0R1}
+ {
+ Locals: [System.Char c]
+ Block[B5#0R1] - Block
+ Predecessors: [B4#0R1]
+ Statements (2)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: null, IsImplicit) (Syntax: 'var')
+ Left:
+ ILocalReferenceOperation: c (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Char, IsImplicit) (Syntax: 'var')
+ Right:
+ IPropertyReferenceOperation: System.Char System.CharEnumerator.Current { get; } (OperationKind.PropertyReference, Type: System.Char, IsImplicit) (Syntax: 'var')
+ Instance Receiver:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ IReturnOperation (OperationKind.YieldReturn, Type: null) (Syntax: 'yield return c;')
+ ReturnedValue:
+ ILocalReferenceOperation: c (OperationKind.LocalReference, Type: System.Char) (Syntax: 'c')
+ Next (Regular) Block[B4#0R1]
+ Leaving: {R4#0R1}
+ }
+ }
+ .finally {R5#0R1}
+ {
+ Block[B6#0R1] - Block
+ Predecessors (0)
+ Statements (0)
+ Jump if True (Regular) to Block[B8#0R1]
+ IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 's')
+ Operand:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Next (Regular) Block[B7#0R1]
+ Block[B7#0R1] - Block
+ Predecessors: [B6#0R1]
+ Statements (1)
+ IInvocationOperation (virtual void System.IDisposable.Dispose()) (OperationKind.Invocation, Type: System.Void, IsImplicit) (Syntax: 's')
+ Instance Receiver:
+ IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: System.IDisposable, IsImplicit) (Syntax: 's')
+ Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
+ (ImplicitReference)
+ Operand:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: System.CharEnumerator, IsImplicit) (Syntax: 's')
+ Arguments(0)
+ Next (Regular) Block[B8#0R1]
+ Block[B8#0R1] - Block
+ Predecessors: [B6#0R1] [B7#0R1]
+ Statements (0)
+ Next (StructuredExceptionHandling) Block[null]
+ }
+ }
+ Block[B9#0R1] - Exit
+ Predecessors: [B4#0R1]
+ Statements (0)
+ }
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedEmptyIterator()
+ {
+ var source = @"
+using System.Collections.Generic;
+class C
+{
+ public static void Main() { }
+ static IEnumerable GetChars(string s!)
+ {
+ yield break;
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'static IEnu ... }')
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IReturnOperation (OperationKind.YieldBreak, Type: null) (Syntax: 'yield break;')
+ ReturnedValue:
+ null
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'static IEnu ... }')
+ Left:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'static IEnu ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'static IEnu ... }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'static IEnu ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'static IEnu ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'static IEnu ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestIOp_NullCheckedEmptyIteratorReturningIEnumerator()
+ {
+ var source = @"
+using System.Collections.Generic;
+class C
+{
+ public static void Main() { }
+ static IEnumerator GetChars(string s!)
+ {
+ yield break;
+ }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'static IEnu ... }')
+ BlockBody:
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ ... }')
+ IReturnOperation (OperationKind.YieldBreak, Type: null) (Syntax: 'yield break;')
+ ReturnedValue:
+ null
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'static IEnu ... }')
+ Left:
+ IParameterReferenceOperation: s (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'static IEnu ... }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'static IEnu ... }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'static IEnu ... }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'static IEnu ... }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""s"", IsImplicit) (Syntax: 'static IEnu ... }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestNullCheckedLambdaWithMissingType()
+ {
+ var source =
+@"
+using System;
+class Program
+{
+ public static void Main()
+ {
+ Func func = x! => x;
+ }
+}
+
+";
+ var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+ comp.MakeMemberMissing(WellKnownMember.System_ArgumentNullException__ctorString);
+ comp.MakeTypeMissing(WellKnownType.System_ArgumentNullException);
+ comp.VerifyDiagnostics(
+ Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "x").WithArguments("System.ArgumentNullException", ".ctor").WithLocation(7, 37));
+ var tree = comp.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ comp.VerifyOperationTree(node1, expectedOperationTree: @"
+IMethodBodyOperation (OperationKind.MethodBody, Type: null, IsInvalid) (Syntax: 'public stat ... }')
+ BlockBody:
+ IBlockOperation (1 statements, 1 locals) (OperationKind.Block, Type: null, IsInvalid) (Syntax: '{ ... }')
+ Locals: Local_1: System.Func func
+ IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null, IsInvalid) (Syntax: 'Func x;')
+ IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null, IsInvalid) (Syntax: 'Func x')
+ Declarators:
+ IVariableDeclaratorOperation (Symbol: System.Func func) (OperationKind.VariableDeclarator, Type: null, IsInvalid) (Syntax: 'func = x! => x')
+ Initializer:
+ IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null, IsInvalid) (Syntax: '= x! => x')
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Target:
+ IAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.AnonymousFunction, Type: null, IsInvalid) (Syntax: 'x! => x')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null, IsImplicit) (Syntax: 'x')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: 'x')
+ ReturnedValue:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Initializer:
+ null
+ ExpressionBody:
+ null");
+ VerifyFlowGraph(comp, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Locals: [System.Func func]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ ISimpleAssignmentOperation (OperationKind.SimpleAssignment, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'func = x! => x')
+ Left:
+ ILocalReferenceOperation: func (IsDeclaration: True) (OperationKind.LocalReference, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'func = x! => x')
+ Right:
+ IDelegateCreationOperation (OperationKind.DelegateCreation, Type: System.Func, IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Target:
+ IFlowAnonymousFunctionOperation (Symbol: lambda expression) (OperationKind.FlowAnonymousFunction, Type: null, IsInvalid) (Syntax: 'x! => x')
+ {
+ Block[B0#A0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#A0]
+ Block[B1#A0] - Block
+ Predecessors: [B0#A0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#A0]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Next (Regular) Block[B2#A0]
+ Block[B2#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Throw) Block[null]
+ IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Children(1):
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsInvalid, IsImplicit) (Syntax: 'x! => x')
+ Block[B3#A0] - Block
+ Predecessors: [B1#A0]
+ Statements (0)
+ Next (Return) Block[B4#A0]
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String) (Syntax: 'x')
+ Block[B4#A0] - Exit
+ Predecessors: [B3#A0]
+ Statements (0)
+ }
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestNullCheckedLocalFunctionWithMissingType()
+ {
+ var source =
+@"
+class Program
+{
+ public static void Main()
+ {
+ M(""ok"");
+ void M(string x!) { }
+ }
+}";
+ var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+ comp.MakeMemberMissing(WellKnownMember.System_ArgumentNullException__ctorString);
+ comp.MakeTypeMissing(WellKnownType.System_ArgumentNullException);
+ comp.VerifyDiagnostics(
+ // (7,23): error CS0656: Missing compiler required member 'System.ArgumentNullException..ctor'
+ // void M(string x!) { }
+ Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "x").WithArguments("System.ArgumentNullException", ".ctor").WithLocation(7, 23));
+ var tree = comp.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+ var node2 = tree.GetRoot().DescendantNodes().OfType().Single();
+ comp.VerifyOperationTree(node1, expectedOperationTree: @"
+ ILocalFunctionOperation (Symbol: void M(System.String x)) (OperationKind.LocalFunction, Type: null, IsInvalid) (Syntax: 'void M(string x!) { }')
+ IBlockOperation (1 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ IReturnOperation (OperationKind.Return, Type: null, IsImplicit) (Syntax: '{ }')
+ ReturnedValue:
+ null");
+ VerifyFlowGraph(comp, node2, @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Entering: {R1}
+.locals {R1}
+{
+ Methods: [void M(System.String x)]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null) (Syntax: 'M(""ok"");')
+ Expression:
+ IInvocationOperation (void M(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: 'M(""ok"")')
+ Instance Receiver:
+ null
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: '""ok""')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""ok"") (Syntax: '""ok""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B2]
+ Leaving: {R1}
+
+ { void M(System.String x)
+
+ Block[B0#0R1] - Entry
+ Statements (0)
+ Next (Regular) Block[B1#0R1]
+ Block[B1#0R1] - Block
+ Predecessors: [B0#0R1]
+ Statements (0)
+ Jump if False (Regular) to Block[B3#0R1]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
+ Left:
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.String, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
+ Next (Regular) Block[B2#0R1]
+ Block[B2#0R1] - Block
+ Predecessors: [B1#0R1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IInvalidOperation (OperationKind.Invalid, Type: null, IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
+ Children(1):
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsInvalid, IsImplicit) (Syntax: 'void M(string x!) { }')
+ Block[B3#0R1] - Exit
+ Predecessors: [B1#0R1]
+ Statements (0)
+ }
+}
+Block[B2] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestNullCheckedMethodWithMissingHasValue()
+ {
+ var source =
+@"
+class Program
+{
+ public void Method(int? x!) { }
+}";
+ var comp = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+ comp.MakeMemberMissing(SpecialMember.System_Nullable_T_get_HasValue);
+ comp.VerifyDiagnostics(
+ // (4,29): warning CS8721: Nullable value type 'int?' is null-checked and will throw if null.
+ // public void Method(int? x!) { }
+ Diagnostic(ErrorCode.WRN_NullCheckingOnNullableValueType, "x").WithArguments("int?").WithLocation(4, 29));
+ var tree = comp.SyntaxTrees.Single();
+ var node = tree.GetRoot().DescendantNodes().OfType().Single();
+ comp.VerifyOperationTree(node, expectedOperationTree: @"
+ IMethodBodyOperation (OperationKind.MethodBody, Type: null) (Syntax: 'public void ... nt? x!) { }')
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+ VerifyFlowGraph(comp, node, @"
+ Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+ Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if True (Regular) to Block[B3]
+ IInvalidOperation (OperationKind.Invalid, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
+ Children(1):
+ IParameterReferenceOperation: x (OperationKind.ParameterReference, Type: System.Int32?, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
+ Next (Regular) Block[B2]
+ Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... nt? x!) { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""x"", IsImplicit) (Syntax: 'public void ... nt? x!) { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+ Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)");
+ }
+
+ [Fact]
+ public void TestNoNullChecksInBlockOperation()
+ {
+ // PROTOTYPE - Nullchecks currently included when only BlockSyntax is bound. Falls into VisitMethodBody instead of VisitBlock.
+ var source = @"
+public class C
+{
+ public void M(string input!)
+ /**/{ }/* */
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().Single();
+
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+");
+ var output = @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public void ... */{ }')
+ Left:
+ IParameterReferenceOperation: input (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public void ... */{ }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public void ... */{ }')
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public void ... */{ }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public void ... */{ }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""input"", IsImplicit) (Syntax: 'public void ... */{ }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+Block[B3] - Exit
+ Predecessors: [B1]
+ Statements (0)";
+ VerifyFlowGraphAndDiagnosticsForTest(compilation, expectedFlowGraph: output, DiagnosticDescription.None);
+ }
+
+ [Fact]
+ public void TestNullCheckedBaseCallOrdering()
+ {
+ var source = @"
+public class B
+{
+ public B(string x) { }
+}
+public class C : B
+{
+ public C(string param!) : base(param ?? """") { }
+}";
+ var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
+
+ compilation.VerifyDiagnostics();
+
+ var tree = compilation.SyntaxTrees.Single();
+ var node1 = tree.GetRoot().DescendantNodes().OfType().ElementAt(1);
+ compilation.VerifyOperationTree(node1, expectedOperationTree: @"
+IConstructorBodyOperation (OperationKind.ConstructorBody, Type: null) (Syntax: 'public C(st ... ?? """") { }')
+ Initializer:
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(param ?? """")')
+ Expression:
+ IInvocationOperation ( B..ctor(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(param ?? """")')
+ Instance Receiver:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(param ?? """")')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: 'param ?? """"')
+ ICoalesceOperation (OperationKind.Coalesce, Type: System.String) (Syntax: 'param ?? """"')
+ Expression:
+ IParameterReferenceOperation: param (OperationKind.ParameterReference, Type: System.String) (Syntax: 'param')
+ ValueConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ (Identity)
+ WhenNull:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ BlockBody:
+ IBlockOperation (0 statements) (OperationKind.Block, Type: null) (Syntax: '{ }')
+ ExpressionBody:
+ null");
+
+ VerifyFlowGraph(compilation, node1, expectedFlowGraph: @"
+Block[B0] - Entry
+ Statements (0)
+ Next (Regular) Block[B1]
+Block[B1] - Block
+ Predecessors: [B0]
+ Statements (0)
+ Jump if False (Regular) to Block[B3]
+ IBinaryOperation (BinaryOperatorKind.Equals) (OperationKind.Binary, Type: System.Boolean, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
+ Left:
+ IParameterReferenceOperation: param (OperationKind.ParameterReference, Type: System.String, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
+ Right:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: null, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
+ Entering: {R1}
+ Next (Regular) Block[B2]
+Block[B2] - Block
+ Predecessors: [B1]
+ Statements (0)
+ Next (Throw) Block[null]
+ IObjectCreationOperation (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreation, Type: System.ArgumentNullException, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument, Type: null, IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: ""param"", IsImplicit) (Syntax: 'public C(st ... ?? """") { }')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Initializer:
+ null
+.locals {R1}
+{
+ CaptureIds: [0] [2]
+ Block[B3] - Block
+ Predecessors: [B1]
+ Statements (1)
+ IFlowCaptureOperation: 0 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: ': base(param ?? """")')
+ Value:
+ IInstanceReferenceOperation (ReferenceKind: ContainingTypeInstance) (OperationKind.InstanceReference, Type: B, IsImplicit) (Syntax: ': base(param ?? """")')
+ Next (Regular) Block[B4]
+ Entering: {R2}
+ .locals {R2}
+ {
+ CaptureIds: [1]
+ Block[B4] - Block
+ Predecessors: [B3]
+ Statements (1)
+ IFlowCaptureOperation: 1 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'param')
+ Value:
+ IParameterReferenceOperation: param (OperationKind.ParameterReference, Type: System.String) (Syntax: 'param')
+ Jump if True (Regular) to Block[B6]
+ IIsNullOperation (OperationKind.IsNull, Type: System.Boolean, IsImplicit) (Syntax: 'param')
+ Operand:
+ IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'param')
+ Leaving: {R2}
+ Next (Regular) Block[B5]
+ Block[B5] - Block
+ Predecessors: [B4]
+ Statements (1)
+ IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: 'param')
+ Value:
+ IFlowCaptureReferenceOperation: 1 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'param')
+ Next (Regular) Block[B7]
+ Leaving: {R2}
+ }
+ Block[B6] - Block
+ Predecessors: [B4]
+ Statements (1)
+ IFlowCaptureOperation: 2 (OperationKind.FlowCapture, Type: null, IsImplicit) (Syntax: '""""')
+ Value:
+ ILiteralOperation (OperationKind.Literal, Type: System.String, Constant: """") (Syntax: '""""')
+ Next (Regular) Block[B7]
+ Block[B7] - Block
+ Predecessors: [B5] [B6]
+ Statements (1)
+ IExpressionStatementOperation (OperationKind.ExpressionStatement, Type: null, IsImplicit) (Syntax: ': base(param ?? """")')
+ Expression:
+ IInvocationOperation ( B..ctor(System.String x)) (OperationKind.Invocation, Type: System.Void) (Syntax: ': base(param ?? """")')
+ Instance Receiver:
+ IFlowCaptureReferenceOperation: 0 (OperationKind.FlowCaptureReference, Type: B, IsImplicit) (Syntax: ': base(param ?? """")')
+ Arguments(1):
+ IArgumentOperation (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument, Type: null) (Syntax: 'param ?? """"')
+ IFlowCaptureReferenceOperation: 2 (OperationKind.FlowCaptureReference, Type: System.String, IsImplicit) (Syntax: 'param ?? """"')
+ InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
+ Next (Regular) Block[B8]
+ Leaving: {R1}
+}
+Block[B8] - Exit
+ Predecessors: [B7]
+ Statements (0)");
+ }
+ }
+}
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/NullCheckedParameterTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/NullCheckedParameterTests.cs
index 456d956965a59..143ebf18b961e 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/NullCheckedParameterTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/NullCheckedParameterTests.cs
@@ -1,4 +1,6 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+// 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.Diagnostics;
using System.Linq;
@@ -210,7 +212,7 @@ void M2(__arglist!)
{
}
}";
- CreateCompilation(source, parseOptions: TestOptions.RegularPreview).VerifyDiagnostics(
+ CreateCompilation(source, parseOptions: TestOptions.RegularPreview).VerifyDiagnostics(
// (8,22): error CS1003: Syntax error, ',' expected
// void M2(__arglist!)
Diagnostic(ErrorCode.ERR_SyntaxError, "!").WithArguments(",", "!").WithLocation(8, 22));
@@ -337,8 +339,8 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- var lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
}
[Fact]
@@ -364,9 +366,9 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- var lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
- Assert.False(((SourceParameterSymbol)lambdaSymbol.Parameters[1]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
+ Assert.False(methodSymbol.Parameters[1].IsNullChecked);
}
[Fact]
@@ -392,8 +394,8 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- LambdaSymbol lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
}
[Fact]
@@ -437,8 +439,8 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- LambdaSymbol lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
}
[Fact]
@@ -464,9 +466,9 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- LambdaSymbol lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
- Assert.False(((SourceParameterSymbol)lambdaSymbol.Parameters[1]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
+ Assert.False(methodSymbol.Parameters[1].IsNullChecked);
}
[Fact]
@@ -492,9 +494,9 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- LambdaSymbol lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[1]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
+ Assert.True(methodSymbol.Parameters[1].IsNullChecked);
}
[Fact]
@@ -520,8 +522,8 @@ public void M()
.DescendantNodes()
.OfType()
.Single();
- LambdaSymbol lambdaSymbol = (LambdaSymbol)model.GetSymbolInfo(node).Symbol;
- Assert.True(((SourceParameterSymbol)lambdaSymbol.Parameters[0]).IsNullChecked);
+ var methodSymbol = (IMethodSymbol)model.GetSymbolInfo(node).Symbol;
+ Assert.True(methodSymbol.Parameters[0].IsNullChecked);
}
[Fact]
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs
index 8836bb721f44b..bfae864efaf5a 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/DeclarationParsingTests.cs
@@ -7241,7 +7241,7 @@ public void TestOptParamMethodDeclarationWithNullValidation()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestOptParamMethodDeclarationWithNullValidationNoSpaces()
{
UsingStatement(@"void M(string name!=null) { }", options: TestOptions.RegularPreview, expectedErrors: new DiagnosticDescription[]
@@ -7319,7 +7319,7 @@ public void TestNullCheckedArgList()
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedArgWithLeadingSpace()
{
UsingStatement(@"void M(string name !=null) { }", options: TestOptions.RegularPreview, expectedErrors: new DiagnosticDescription[]
@@ -7365,7 +7365,7 @@ public void TestNullCheckedArgWithLeadingSpace()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedArgWithLeadingNewLine()
{
UsingStatement(@"void M(string name
@@ -7412,7 +7412,7 @@ public void TestNullCheckedArgWithLeadingNewLine()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedArgWithTrailingSpace()
{
UsingStatement(@"void M(string name!= null) { }", options: TestOptions.RegularPreview, expectedErrors: new DiagnosticDescription[]
@@ -7458,7 +7458,7 @@ public void TestNullCheckedArgWithTrailingSpace()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedArgWithTrailingNewLine()
{
UsingStatement(@"void M(string name!=
@@ -7505,7 +7505,7 @@ public void TestNullCheckedArgWithTrailingNewLine()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedMethod()
{
UsingTree(@"
@@ -7552,7 +7552,7 @@ public void M(string x!) { }
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedConstructor()
{
UsingTree(@"
@@ -7669,7 +7669,7 @@ class Box
N(SyntaxKind.EndOfFileToken);
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestAnonymousDelegateNullChecking()
{
// PROTOTYPE : During semantics, make sure this causes an error
@@ -7743,6 +7743,8 @@ public void TestAnonymousDelegateNullChecking()
}
N(SyntaxKind.SemicolonToken);
}
+ }
+
[Fact, WorkItem(30102, "https://github.com/dotnet/roslyn/issues/30102")]
public void IncompleteGenericInBaseList1()
{
diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
index 19779cff4517c..b53e8e968b9f0 100644
--- a/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Parsing/LambdaParameterParsingTests.cs
@@ -771,7 +771,7 @@ public void TestNullCheckedSingleParamInParens()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedSingleParamNoSpaces()
{
UsingDeclaration("Func func1 = x!=>x;", options: TestOptions.RegularPreview, expectedErrors: new DiagnosticDescription[]
@@ -1032,7 +1032,7 @@ public void TestManyNullCheckedTypedParams()
}
}
- [Fact]
+ [Fact(Skip = "PROTOTYPE(BangBang)")]
public void TestNullCheckedNoParams()
{
UsingDeclaration("Func