提交 473f8302 编写于 作者: M Manish Vasani

Merge remote-tracking branch 'upstream/features/ioperation' into LoopStatements

......@@ -46,7 +46,7 @@
<MicrosoftMetadataVisualizerVersion>1.0.0-beta1-61531-03</MicrosoftMetadataVisualizerVersion>
<MicrosoftMSXMLVersion>8.0.0.0-alpha</MicrosoftMSXMLVersion>
<MicrosoftNetCompilersVersion>2.6.0-beta1-61906-08</MicrosoftNetCompilersVersion>
<MicrosoftNetRoslynDiagnosticsVersion>2.5.0-beta1-61924-01</MicrosoftNetRoslynDiagnosticsVersion>
<MicrosoftNetRoslynDiagnosticsVersion>2.5.0-beta1-62011-01</MicrosoftNetRoslynDiagnosticsVersion>
<MicrosoftNetCoreILAsmVersion>1.1.0</MicrosoftNetCoreILAsmVersion>
<MicrosoftNETCoreCompilersVersion>2.3.1-beta1-61919-13</MicrosoftNETCoreCompilersVersion>
<MicrosoftNETCoreVersion>5.0.0</MicrosoftNETCoreVersion>
......
......@@ -23,3 +23,5 @@ Consider the case where the type of `a` is `System.Func<bool>` and you write `va
- https://github.com/dotnet/roslyn/issues/17963 In C# 7.0 and before C# 7.1, the compiler used to consider tuple element name differences and dynamic-ness differences as significant when using the "as" operator with a nullable tuple type. For instance, `(1, 1) as (int, int x)?` and `(1, new object()) as (int, dynamic)?` would always be considered `null`. The compiler now produces the correct value, instead of `null`, and no "always null" warning.
- https://github.com/dotnet/roslyn/issues/20208 In C# 7.0 and before C# 7.2, the compiler considered a local declared with a `var` type and a tuple literal value to be used. So it would not report a warning if that local was not used. The compiler now produces a diagnostic. For example, `var unused = (1, 2);`.
- https://github.com/dotnet/roslyn/issues/20873 In Roslyn 2.3, the `includePrivateMembers` parameter of the `EmitOptions` constructor was changed to use `true` as its default value. This is a binary compatibility break. So clients using this API may have to re-compile, to pick up the new default value. An update will include a mitigation (ignoring the old default value when trying to emit a full assembly).
......@@ -5,3 +5,5 @@ Changes since VS2017 (VB 15)
In VB 15, elements in tuple literals can be named explicitly, but in VB 15.3, elements that aren't named explicitly will get an inferred named. This uses the same rules as members in anonymous types which aren't named explicitly.
For instance, `Dim t = (a, b.c, Me.d)` will produce a tuple with element names "a", "c" and "d". As a result, an invocation on a tuple member may result in a different result than it did in VB 15.
Consider the case where the type of `a` is `System.Func(Of Boolean)` and you write `Dim local = t.a()`. This will now find the first element of the tuple and invoke it, whereas previously it could only mean "invoke an extension method named 'a'".
- https://github.com/dotnet/roslyn/issues/20873 In Roslyn 2.3, the `includePrivateMembers` parameter of the `EmitOptions` constructor was changed to use `true` as its default value. This is a binary compatibility break. So clients using this API may have to re-compile, to pick up the new default value. An update will include a mitigation (ignoring the old default value when trying to emit a full assembly).
......@@ -192,7 +192,7 @@ commitPullList.each { isPr ->
def triggerPhraseOnly = false
def triggerPhraseExtra = "perf-correctness"
Utilities.setMachineAffinity(myJob, 'Windows_NT', 'latest-dev15-3-preview2')
Utilities.setMachineAffinity(myJob, 'Windows_NT', 'latest-dev15-3')
addRoslynJob(myJob, jobName, branchName, isPr, triggerPhraseExtra, triggerPhraseOnly)
}
......
......@@ -1030,8 +1030,7 @@ public override object VisitField(FieldSymbol symbol, TypeCompilationState argum
return semanticModel;
});
MethodSymbol symbolToProduce = methodSymbol.PartialDefinitionPart ?? methodSymbol;
_compilation.EventQueue.TryEnqueue(new SymbolDeclaredCompilationEvent(_compilation, symbolToProduce, lazySemanticModel));
_compilation.EventQueue.TryEnqueue(new SymbolDeclaredCompilationEvent(_compilation, methodSymbol, lazySemanticModel));
}
// Don't lower if we're not emitting or if there were errors.
......
......@@ -333,7 +333,7 @@ private void SynthesizeClosureEnvironments(ArrayBuilder<ClosureDebugInfo> closur
Debug.Assert(scope.DeclaredEnvironments.Count == 1);
var env = scope.DeclaredEnvironments[0];
var frame = MakeFrame(scope, env.IsStruct);
var frame = MakeFrame(scope, env);
env.SynthesizedEnvironment = frame;
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(ContainingType, frame);
......@@ -346,20 +346,11 @@ private void SynthesizeClosureEnvironments(ArrayBuilder<ClosureDebugInfo> closur
frame.Constructor));
}
foreach (var captured in env.CapturedVariables)
{
Debug.Assert(!proxies.ContainsKey(captured));
var hoistedField = LambdaCapturedVariable.Create(frame, captured, ref _synthesizedFieldNameIdDispenser);
proxies.Add(captured, new CapturedToFrameSymbolReplacement(hoistedField, isReusable: false));
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(frame, hoistedField);
}
_frames.Add(scope.BoundNode, env);
}
});
SynthesizedClosureEnvironment MakeFrame(Analysis.Scope scope, bool isStruct)
SynthesizedClosureEnvironment MakeFrame(Analysis.Scope scope, Analysis.ClosureEnvironment env)
{
var scopeBoundNode = scope.BoundNode;
......@@ -375,13 +366,25 @@ SynthesizedClosureEnvironment MakeFrame(Analysis.Scope scope, bool isStruct)
containingMethod = _substitutedSourceMethod;
}
return new SynthesizedClosureEnvironment(
var synthesizedEnv = new SynthesizedClosureEnvironment(
_topLevelMethod,
containingMethod,
isStruct,
env.IsStruct,
syntax,
methodId,
closureId);
foreach (var captured in env.CapturedVariables)
{
Debug.Assert(!proxies.ContainsKey(captured));
var hoistedField = LambdaCapturedVariable.Create(synthesizedEnv, captured, ref _synthesizedFieldNameIdDispenser);
proxies.Add(captured, new CapturedToFrameSymbolReplacement(hoistedField, isReusable: false));
synthesizedEnv.AddHoistedField(hoistedField);
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(synthesizedEnv, hoistedField);
}
return synthesizedEnv;
}
}
......@@ -515,7 +518,7 @@ private SynthesizedClosureEnvironment GetStaticFrame(DiagnosticBag diagnostics,
var frame = _lazyStaticLambdaFrame;
// add frame type
// add frame type and cache field
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(this.ContainingType, frame);
// add its ctor (note Constructor can be null if TypeKind.Struct is passed in to LambdaFrame.ctor, but Class is passed in above)
......@@ -661,6 +664,7 @@ private BoundNode IntroduceFrame(BoundNode node, Analysis.ClosureEnvironment env
if (CompilationState.Emitting)
{
Debug.Assert(capturedFrame.Type.IsReferenceType); // Make sure we're not accidentally capturing a struct by value
frame.AddHoistedField(capturedFrame);
CompilationState.ModuleBuilderOpt.AddSynthesizedDefinition(frame, capturedFrame);
}
......@@ -1331,7 +1335,7 @@ private DebugId GetLambdaId(SyntaxNode syntax, ClosureKind closureKind, int clos
}
else if (localFunction != null)
{
lambdaOrLambdaBodySyntax = (SyntaxNode)localFunction.Body ?? localFunction.ExpressionBody;
lambdaOrLambdaBodySyntax = (SyntaxNode)localFunction.Body ?? localFunction.ExpressionBody?.Expression;
isLambdaBody = true;
}
else if (LambdaUtilities.IsQueryPairLambda(syntax))
......
......@@ -5,6 +5,8 @@
using System.Diagnostics;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
......@@ -25,6 +27,9 @@ internal sealed class SynthesizedClosureEnvironment : SynthesizedContainer, ISyn
internal readonly FieldSymbol SingletonCache;
internal readonly MethodSymbol StaticConstructor;
private ArrayBuilder<Symbol> _membersBuilder = ArrayBuilder<Symbol>.GetInstance();
private ImmutableArray<Symbol> _members;
public override TypeKind TypeKind { get; }
internal override MethodSymbol Constructor { get; }
......@@ -55,6 +60,8 @@ internal sealed class SynthesizedClosureEnvironment : SynthesizedContainer, ISyn
this.ScopeSyntaxOpt = scopeSyntaxOpt;
}
internal void AddHoistedField(LambdaCapturedVariable captured) => _membersBuilder.Add(captured);
private static string MakeName(SyntaxNode scopeSyntaxOpt, DebugId methodId, DebugId closureId)
{
if (scopeSyntaxOpt == null)
......@@ -89,15 +96,31 @@ private static void AssertIsClosureScopeSyntax(SyntaxNode syntaxOpt)
public override ImmutableArray<Symbol> GetMembers()
{
var members = base.GetMembers();
if ((object)StaticConstructor != null)
if (_members.IsDefault)
{
members = ImmutableArray.Create<Symbol>(StaticConstructor, SingletonCache).AddRange(members);
var builder = _membersBuilder;
if ((object)StaticConstructor != null)
{
builder.Add(StaticConstructor);
builder.Add(SingletonCache);
}
builder.AddRange(base.GetMembers());
_members = builder.ToImmutableAndFree();
_membersBuilder = null;
}
return members;
return _members;
}
/// <summary>
/// All fields should have already been added as synthesized members on the
/// <see cref="CommonPEModuleBuilder" />, so we don't want to duplicate them here.
/// </summary>
internal override IEnumerable<FieldSymbol> GetFieldsToEmit()
=> (object)SingletonCache != null
? SpecializedCollections.SingletonEnumerable(SingletonCache)
: SpecializedCollections.EmptyEnumerable<FieldSymbol>();
// display classes for static lambdas do not have any data and can be serialized.
internal override bool IsSerializable => (object)SingletonCache != null;
......
......@@ -2091,14 +2091,28 @@ private BoundExpression MakeSizeOfMultiplication(BoundExpression numericOperand,
{
case SpecialType.System_Int32:
// add operator can take int32 and extend to 64bit if necessary
// however in a case of checked operation, the operation is treated as unsigned with overflow ( add.ovf.un , sub.ovf.un )
// the IL spec is a bit vague whether JIT should sign or zero extend the shorter operand in such case
// and there could be inconsistencies in implementation or bugs.
// As a result, in checked contexts, we will force sign-extending cast to be sure
if (isChecked)
{
var constVal = numericOperand.ConstantValue;
if (constVal == null || constVal.Int32Value < 0)
{
destinationType = SpecialType.System_IntPtr;
}
}
break;
case SpecialType.System_UInt32:
// add operator treats operands as signed and will sign-extend on x64
// to prevent sign-extending, convert the operand to unsigned native int.
var constVal = numericOperand.ConstantValue;
if (constVal == null || constVal.UInt32Value > int.MaxValue)
{
destinationType = SpecialType.System_UIntPtr;
// add operator treats operands as signed and will sign-extend on x64
// to prevent sign-extending, convert the operand to unsigned native int.
var constVal = numericOperand.ConstantValue;
if (constVal == null || constVal.UInt32Value > int.MaxValue)
{
destinationType = SpecialType.System_UIntPtr;
}
}
break;
case SpecialType.System_Int64:
......
......@@ -532,8 +532,7 @@ private IObjectOrCollectionInitializerExpression CreateBoundCollectionInitialize
private IMemberReferenceExpression CreateBoundObjectInitializerMemberOperation(BoundObjectInitializerMember boundObjectInitializerMember)
{
Lazy<IOperation> instance = new Lazy<IOperation>(() => new InstanceReferenceExpression(
InstanceReferenceKind.Implicit,
_semanticModel,
semanticModel: _semanticModel,
syntax: boundObjectInitializerMember.Syntax,
type: boundObjectInitializerMember.MemberSymbol.ContainingType,
constantValue: default(Optional<object>),
......@@ -655,13 +654,13 @@ private IAnonymousFunctionExpression CreateBoundLambdaOperation(BoundLambda boun
private ILocalFunctionStatement CreateBoundLocalFunctionStatementOperation(BoundLocalFunctionStatement boundLocalFunctionStatement)
{
IMethodSymbol localFunctionSymbol = boundLocalFunctionStatement.Symbol;
IMethodSymbol symbol = boundLocalFunctionStatement.Symbol;
Lazy<IBlockStatement> body = new Lazy<IBlockStatement>(() => (IBlockStatement)Create(boundLocalFunctionStatement.Body));
SyntaxNode syntax = boundLocalFunctionStatement.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundLocalFunctionStatement.WasCompilerGenerated;
return new LazyLocalFunctionStatement(localFunctionSymbol, body, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyLocalFunctionStatement(symbol, body, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IOperation CreateBoundConversionOperation(BoundConversion boundConversion)
......@@ -682,7 +681,7 @@ private IOperation CreateBoundConversionOperation(BoundConversion boundConversio
{
Lazy<IOperation> operand = new Lazy<IOperation>(() => Create(boundConversion.Operand));
SyntaxNode syntax = boundConversion.Syntax;
Conversion conversion = _semanticModel.GetConversion(syntax);
Conversion conversion = boundConversion.Conversion;
bool isExplicit = boundConversion.ExplicitCastInCode;
bool isTryCast = false;
// Checked conversions only matter if the conversion is a Numeric conversion. Don't have true unless the conversion is actually numeric.
......@@ -697,7 +696,7 @@ private IConversionExpression CreateBoundAsOperatorOperation(BoundAsOperator bou
{
Lazy<IOperation> operand = new Lazy<IOperation>(() => Create(boundAsOperator.Operand));
SyntaxNode syntax = boundAsOperator.Syntax;
Conversion conversion = _semanticModel.GetConversion(syntax);
Conversion conversion = boundAsOperator.Conversion;
bool isExplicit = true;
bool isTryCast = true;
bool isChecked = false;
......@@ -771,22 +770,20 @@ private IDefaultValueExpression CreateBoundDefaultExpressionOperation(BoundDefau
private IInstanceReferenceExpression CreateBoundBaseReferenceOperation(BoundBaseReference boundBaseReference)
{
InstanceReferenceKind instanceReferenceKind = InstanceReferenceKind.BaseClass;
SyntaxNode syntax = boundBaseReference.Syntax;
ITypeSymbol type = boundBaseReference.Type;
Optional<object> constantValue = ConvertToOptional(boundBaseReference.ConstantValue);
bool isImplicit = boundBaseReference.WasCompilerGenerated;
return new InstanceReferenceExpression(instanceReferenceKind, _semanticModel, syntax, type, constantValue, isImplicit);
return new InstanceReferenceExpression(_semanticModel, syntax, type, constantValue, isImplicit);
}
private IInstanceReferenceExpression CreateBoundThisReferenceOperation(BoundThisReference boundThisReference)
{
InstanceReferenceKind instanceReferenceKind = boundThisReference.Syntax.Kind() == SyntaxKind.ThisExpression ? InstanceReferenceKind.Explicit : InstanceReferenceKind.Implicit;
SyntaxNode syntax = boundThisReference.Syntax;
ITypeSymbol type = boundThisReference.Type;
Optional<object> constantValue = ConvertToOptional(boundThisReference.ConstantValue);
bool isImplicit = boundThisReference.WasCompilerGenerated;
return new InstanceReferenceExpression(instanceReferenceKind, _semanticModel, syntax, type, constantValue, isImplicit);
return new InstanceReferenceExpression(_semanticModel, syntax, type, constantValue, isImplicit);
}
private IOperation CreateBoundAssignmentOperatorOrMemberInitializerOperation(BoundAssignmentOperator boundAssignmentOperator)
......@@ -827,29 +824,34 @@ private IMemberInitializerExpression CreateBoundMemberInitializerOperation(Bound
private ICompoundAssignmentExpression CreateBoundCompoundAssignmentOperatorOperation(BoundCompoundAssignmentOperator boundCompoundAssignmentOperator)
{
BinaryOperationKind binaryOperationKind = Helper.DeriveBinaryOperationKind(boundCompoundAssignmentOperator.Operator.Kind);
BinaryOperatorKind operatorKind = Helper.DeriveBinaryOperatorKind(boundCompoundAssignmentOperator.Operator.Kind);
Lazy<IOperation> target = new Lazy<IOperation>(() => Create(boundCompoundAssignmentOperator.Left));
Lazy<IOperation> value = new Lazy<IOperation>(() => Create(boundCompoundAssignmentOperator.Right));
bool usesOperatorMethod = (boundCompoundAssignmentOperator.Operator.Kind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined;
bool isLifted = boundCompoundAssignmentOperator.Type.IsNullableType();
bool isChecked = boundCompoundAssignmentOperator.Operator.Kind.IsChecked();
bool usesOperatorMethod = (boundCompoundAssignmentOperator.Operator.Kind & CSharp.BinaryOperatorKind.TypeMask) == CSharp.BinaryOperatorKind.UserDefined;
IMethodSymbol operatorMethod = boundCompoundAssignmentOperator.Operator.Method;
SyntaxNode syntax = boundCompoundAssignmentOperator.Syntax;
ITypeSymbol type = boundCompoundAssignmentOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundCompoundAssignmentOperator.ConstantValue);
bool isImplicit = boundCompoundAssignmentOperator.WasCompilerGenerated;
return new LazyCompoundAssignmentExpression(binaryOperationKind, boundCompoundAssignmentOperator.Type.IsNullableType(), target, value, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyCompoundAssignmentExpression(operatorKind, isLifted, isChecked, target, value, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IIncrementExpression CreateBoundIncrementOperatorOperation(BoundIncrementOperator boundIncrementOperator)
{
UnaryOperationKind incrementOperationKind = Helper.DeriveUnaryOperationKind(boundIncrementOperator.OperatorKind);
bool isDecrement = Helper.IsDecrement(boundIncrementOperator.OperatorKind);
bool isPostfix = Helper.IsPostfixIncrementOrDecrement(boundIncrementOperator.OperatorKind);
bool isLifted = boundIncrementOperator.OperatorKind.IsLifted();
bool isChecked = boundIncrementOperator.OperatorKind.IsChecked();
Lazy<IOperation> target = new Lazy<IOperation>(() => Create(boundIncrementOperator.Operand));
bool usesOperatorMethod = (boundIncrementOperator.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined;
bool usesOperatorMethod = (boundIncrementOperator.OperatorKind & CSharp.UnaryOperatorKind.TypeMask) == CSharp.UnaryOperatorKind.UserDefined;
IMethodSymbol operatorMethod = boundIncrementOperator.MethodOpt;
SyntaxNode syntax = boundIncrementOperator.Syntax;
ITypeSymbol type = boundIncrementOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundIncrementOperator.ConstantValue);
bool isImplicit = boundIncrementOperator.WasCompilerGenerated;
return new LazyIncrementExpression(incrementOperationKind, target, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyIncrementExpression(isDecrement, isPostfix, isLifted, isChecked, target, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IInvalidExpression CreateBoundBadExpressionOperation(BoundBadExpression boundBadExpression)
......@@ -874,31 +876,34 @@ private ITypeParameterObjectCreationExpression CreateBoundNewTOperation(BoundNew
private IUnaryOperatorExpression CreateBoundUnaryOperatorOperation(BoundUnaryOperator boundUnaryOperator)
{
UnaryOperationKind unaryOperationKind = Helper.DeriveUnaryOperationKind(boundUnaryOperator.OperatorKind);
UnaryOperatorKind unaryOperatorKind = Helper.DeriveUnaryOperatorKind(boundUnaryOperator.OperatorKind);
Lazy<IOperation> operand = new Lazy<IOperation>(() => Create(boundUnaryOperator.Operand));
bool usesOperatorMethod = (boundUnaryOperator.OperatorKind & UnaryOperatorKind.TypeMask) == UnaryOperatorKind.UserDefined;
bool usesOperatorMethod = (boundUnaryOperator.OperatorKind & CSharp.UnaryOperatorKind.TypeMask) == CSharp.UnaryOperatorKind.UserDefined;
IMethodSymbol operatorMethod = boundUnaryOperator.MethodOpt;
SyntaxNode syntax = boundUnaryOperator.Syntax;
ITypeSymbol type = boundUnaryOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundUnaryOperator.ConstantValue);
bool isLifted = boundUnaryOperator.OperatorKind.IsLifted();
bool isChecked = boundUnaryOperator.OperatorKind.IsChecked();
bool isImplicit = boundUnaryOperator.WasCompilerGenerated;
return new LazyUnaryOperatorExpression(unaryOperationKind, operand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyUnaryOperatorExpression(unaryOperatorKind, operand, isLifted, isChecked, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IBinaryOperatorExpression CreateBoundBinaryOperatorOperation(BoundBinaryOperator boundBinaryOperator)
{
BinaryOperationKind binaryOperationKind = Helper.DeriveBinaryOperationKind(boundBinaryOperator.OperatorKind);
BinaryOperatorKind operatorKind = Helper.DeriveBinaryOperatorKind(boundBinaryOperator.OperatorKind);
Lazy<IOperation> leftOperand = new Lazy<IOperation>(() => Create(boundBinaryOperator.Left));
Lazy<IOperation> rightOperand = new Lazy<IOperation>(() => Create(boundBinaryOperator.Right));
bool usesOperatorMethod = (boundBinaryOperator.OperatorKind & BinaryOperatorKind.TypeMask) == BinaryOperatorKind.UserDefined;
bool usesOperatorMethod = (boundBinaryOperator.OperatorKind & CSharp.BinaryOperatorKind.TypeMask) == CSharp.BinaryOperatorKind.UserDefined;
IMethodSymbol operatorMethod = boundBinaryOperator.MethodOpt;
SyntaxNode syntax = boundBinaryOperator.Syntax;
ITypeSymbol type = boundBinaryOperator.Type;
Optional<object> constantValue = ConvertToOptional(boundBinaryOperator.ConstantValue);
bool isLifted = boundBinaryOperator.OperatorKind.IsLifted();
bool isChecked = boundBinaryOperator.OperatorKind.IsChecked();
bool isCompareText = false;
bool isImplicit = boundBinaryOperator.WasCompilerGenerated;
return new LazyBinaryOperatorExpression(binaryOperationKind, leftOperand, rightOperand, isLifted, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyBinaryOperatorExpression(operatorKind, leftOperand, rightOperand, isLifted, isChecked, isCompareText, usesOperatorMethod, operatorMethod, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IConditionalExpression CreateBoundConditionalOperatorOperation(BoundConditionalOperator boundConditionalOperator)
......@@ -988,24 +993,23 @@ private IAddressOfExpression CreateBoundAddressOfOperatorOperation(BoundAddressO
private IInstanceReferenceExpression CreateBoundImplicitReceiverOperation(BoundImplicitReceiver boundImplicitReceiver)
{
InstanceReferenceKind instanceReferenceKind = InstanceReferenceKind.Implicit;
SyntaxNode syntax = boundImplicitReceiver.Syntax;
ITypeSymbol type = boundImplicitReceiver.Type;
Optional<object> constantValue = ConvertToOptional(boundImplicitReceiver.ConstantValue);
bool isImplicit = boundImplicitReceiver.WasCompilerGenerated;
return new InstanceReferenceExpression(instanceReferenceKind, _semanticModel, syntax, type, constantValue, isImplicit);
return new InstanceReferenceExpression(_semanticModel, syntax, type, constantValue, isImplicit);
}
private IConditionalAccessExpression CreateBoundConditionalAccessOperation(BoundConditionalAccess boundConditionalAccess)
{
Lazy<IOperation> conditionalValue = new Lazy<IOperation>(() => Create(boundConditionalAccess.AccessExpression));
Lazy<IOperation> conditionalInstance = new Lazy<IOperation>(() => Create(boundConditionalAccess.Receiver));
Lazy<IOperation> whenNotNull = new Lazy<IOperation>(() => Create(boundConditionalAccess.AccessExpression));
Lazy<IOperation> expression = new Lazy<IOperation>(() => Create(boundConditionalAccess.Receiver));
SyntaxNode syntax = boundConditionalAccess.Syntax;
ITypeSymbol type = boundConditionalAccess.Type;
Optional<object> constantValue = ConvertToOptional(boundConditionalAccess.ConstantValue);
bool isImplicit = boundConditionalAccess.WasCompilerGenerated;
return new LazyConditionalAccessExpression(conditionalValue, conditionalInstance, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyConditionalAccessExpression(whenNotNull, expression, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IConditionalAccessInstanceExpression CreateBoundConditionalReceiverOperation(BoundConditionalReceiver boundConditionalReceiver)
......@@ -1219,8 +1223,7 @@ private ICaseClause CreateBoundSwitchLabelOperation(BoundSwitchLabel boundSwitch
if (boundSwitchLabel.ExpressionOpt != null)
{
Lazy<IOperation> value = new Lazy<IOperation>(() => Create(boundSwitchLabel.ExpressionOpt));
BinaryOperationKind equality = GetLabelEqualityKind(boundSwitchLabel);
return new LazySingleValueCaseClause(value, equality, CaseKind.SingleValue, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazySingleValueCaseClause(value, CaseKind.SingleValue, _semanticModel, syntax, type, constantValue, isImplicit);
}
else
{
......@@ -1360,18 +1363,18 @@ private IVariableDeclarationStatement CreateBoundMultipleLocalDeclarationsOperat
return new LazyVariableDeclarationStatement(declarations, _semanticModel, syntax, type, constantValue, isImplicit);
}
private ILabelStatement CreateBoundLabelStatementOperation(BoundLabelStatement boundLabelStatement)
private ILabeledStatement CreateBoundLabelStatementOperation(BoundLabelStatement boundLabelStatement)
{
ILabelSymbol label = boundLabelStatement.Label;
Lazy<IOperation> labeledStatement = new Lazy<IOperation>(() => Create(null));
Lazy<IOperation> statement = new Lazy<IOperation>(() => Create(null));
SyntaxNode syntax = boundLabelStatement.Syntax;
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundLabelStatement.WasCompilerGenerated;
return new LazyLabelStatement(label, labeledStatement, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyLabeledStatement(label, statement, _semanticModel, syntax, type, constantValue, isImplicit);
}
private ILabelStatement CreateBoundLabeledStatementOperation(BoundLabeledStatement boundLabeledStatement)
private ILabeledStatement CreateBoundLabeledStatementOperation(BoundLabeledStatement boundLabeledStatement)
{
ILabelSymbol label = boundLabeledStatement.Label;
Lazy<IOperation> labeledStatement = new Lazy<IOperation>(() => Create(boundLabeledStatement.Body));
......@@ -1379,7 +1382,7 @@ private ILabelStatement CreateBoundLabeledStatementOperation(BoundLabeledStateme
ITypeSymbol type = null;
Optional<object> constantValue = default(Optional<object>);
bool isImplicit = boundLabeledStatement.WasCompilerGenerated;
return new LazyLabelStatement(label, labeledStatement, _semanticModel, syntax, type, constantValue, isImplicit);
return new LazyLabeledStatement(label, labeledStatement, _semanticModel, syntax, type, constantValue, isImplicit);
}
private IExpressionStatement CreateBoundExpressionStatementOperation(BoundExpressionStatement boundExpressionStatement)
......
......@@ -132,7 +132,7 @@ internal sealed class SourceOrdinaryMethodSymbol : SourceMemberMethodSymbol
syntax.Modifiers.Any(SyntaxKind.OverrideKeyword))
{
diagnostics.Add(
ErrorCode.ERR_OverrideWithConstraints,
ErrorCode.ERR_OverrideWithConstraints,
syntax.ConstraintClauses[0].WhereKeyword.GetLocation());
}
}
......@@ -328,8 +328,8 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
if ((object)overriddenMethod != null)
{
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyCustomModifiers,
CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: true);
}
}
......@@ -344,7 +344,7 @@ private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsB
Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault);
_lazyExplicitInterfaceImplementations = ImmutableArray.Create<MethodSymbol>(implementedMethod);
CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType,
out _lazyCustomModifiers,
out _lazyParameters, alsoCopyParamsModifier: false);
}
......@@ -441,7 +441,7 @@ private void CompleteAsyncMethodChecks(DiagnosticBag diagnosticsOpt, Cancellatio
{
AddDeclarationDiagnostics(diagnosticsOpt);
}
if (IsPartialDefinition && (object)PartialImplementationPart == null)
if (IsPartialDefinition)
{
DeclaringCompilation.SymbolDeclaredEvent(this);
}
......
......@@ -47,6 +47,15 @@ public static bool IsLambda(SyntaxNode node)
public static SyntaxNode GetLambda(SyntaxNode lambdaBody)
{
var lambda = lambdaBody.Parent;
if (lambda.Kind() == SyntaxKind.ArrowExpressionClause)
{
// In case of expression bodied local functionsm there is a three level hierarchy:
// LocalFunctionStatement -> ArrowExpressionClause -> Expression.
// And the lambda is the LocalFunctionStatement.
lambda = lambda.Parent;
Debug.Assert(lambda.Kind() == SyntaxKind.LocalFunctionStatement);
}
Debug.Assert(IsLambda(lambda));
return lambda;
}
......@@ -56,8 +65,7 @@ public static SyntaxNode GetLambda(SyntaxNode lambdaBody)
/// </summary>
internal static SyntaxNode TryGetCorrespondingLambdaBody(SyntaxNode oldBody, SyntaxNode newLambda)
{
var oldLambda = oldBody.Parent;
switch (oldLambda.Kind())
switch (newLambda.Kind())
{
case SyntaxKind.ParenthesizedLambdaExpression:
case SyntaxKind.SimpleLambdaExpression:
......@@ -85,24 +93,33 @@ internal static SyntaxNode TryGetCorrespondingLambdaBody(SyntaxNode oldBody, Syn
return IsReducedSelectOrGroupByClause(selectClause, selectClause.Expression) ? null : selectClause.Expression;
case SyntaxKind.JoinClause:
var oldJoin = (JoinClauseSyntax)oldLambda;
var oldJoin = (JoinClauseSyntax)oldBody.Parent;
var newJoin = (JoinClauseSyntax)newLambda;
Debug.Assert(oldJoin.LeftExpression == oldBody || oldJoin.RightExpression == oldBody);
return (oldJoin.LeftExpression == oldBody) ? newJoin.LeftExpression : newJoin.RightExpression;
case SyntaxKind.GroupClause:
var oldGroup = (GroupClauseSyntax)oldLambda;
var oldGroup = (GroupClauseSyntax)oldBody.Parent;
var newGroup = (GroupClauseSyntax)newLambda;
Debug.Assert(oldGroup.GroupExpression == oldBody || oldGroup.ByExpression == oldBody);
return (oldGroup.GroupExpression == oldBody) ?
(IsReducedSelectOrGroupByClause(newGroup, newGroup.GroupExpression) ? null : newGroup.GroupExpression) : newGroup.ByExpression;
case SyntaxKind.LocalFunctionStatement:
var newLocalFunction = (LocalFunctionStatementSyntax)newLambda;
return (SyntaxNode)newLocalFunction.Body ?? newLocalFunction.ExpressionBody;
return GetLocalFunctionBody((LocalFunctionStatementSyntax)newLambda);
default:
throw ExceptionUtilities.UnexpectedValue(oldLambda.Kind());
throw ExceptionUtilities.UnexpectedValue(newLambda.Kind());
}
}
public static SyntaxNode GetNestedFunctionBody(SyntaxNode nestedFunction)
{
switch (nestedFunction)
{
case AnonymousFunctionExpressionSyntax anonymousFunctionExpressionSyntax: return anonymousFunctionExpressionSyntax.Body;
case LocalFunctionStatementSyntax localFunctionStatementSyntax: return (CSharpSyntaxNode)localFunctionStatementSyntax.Body ?? localFunctionStatementSyntax.ExpressionBody.Expression;
default: throw ExceptionUtilities.UnexpectedValue(nestedFunction);
}
}
......@@ -132,7 +149,11 @@ public static bool IsLambdaBody(SyntaxNode node, bool allowReducedLambdas = fals
case SyntaxKind.LocalFunctionStatement:
var localFunction = (LocalFunctionStatementSyntax)parent;
return localFunction.Body == node || localFunction.ExpressionBody == node;
return localFunction.Body == node;
case SyntaxKind.ArrowExpressionClause:
var arrowExpressionClause = (ArrowExpressionClauseSyntax)parent;
return arrowExpressionClause.Expression == node && arrowExpressionClause.Parent is LocalFunctionStatementSyntax;
case SyntaxKind.FromClause:
var fromClause = (FromClauseSyntax)parent;
......@@ -320,8 +341,7 @@ public static bool TryGetLambdaBodies(SyntaxNode node, out SyntaxNode lambdaBody
return true;
case SyntaxKind.LocalFunctionStatement:
var localFunction = (LocalFunctionStatementSyntax)node;
lambdaBody1 = (SyntaxNode)localFunction.Body ?? localFunction.ExpressionBody;
lambdaBody1 = GetLocalFunctionBody((LocalFunctionStatementSyntax)node);
return true;
}
......@@ -419,5 +439,10 @@ internal static bool IsClosureScope(SyntaxNode node)
return false;
}
private static SyntaxNode GetLocalFunctionBody(LocalFunctionStatementSyntax localFunctionStatementSyntax)
{
return (SyntaxNode)localFunctionStatementSyntax.Body ?? localFunctionStatementSyntax.ExpressionBody?.Expression;
}
}
}
......@@ -7703,6 +7703,34 @@ static void Main()
CompileAndVerify(comp, expectedOutput: "once");
}
[WorkItem(21028, "https://github.com/dotnet/roslyn/issues/21028")]
[Fact]
public void InferredName()
{
var source =
@"class C
{
static void Main()
{
int x = 0, y = 1;
var t = (x, y);
var (a, b) = t;
}
}";
// C# 7.0
var comp = CreateStandardCompilation(
source,
parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7),
references: new[] { ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyEmitDiagnostics();
// C# 7.1
comp = CreateStandardCompilation(
source,
parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_1),
references: new[] { ValueTupleRef, SystemRuntimeFacadeRef });
comp.VerifyEmitDiagnostics();
}
[WorkItem(21028, "https://github.com/dotnet/roslyn/issues/21028")]
[Fact]
public void InferredName_ConditionalOperator()
......
......@@ -30,6 +30,306 @@ public static IMethodSymbol FindLocalFunction(this CompilationVerifier verifier,
[CompilerTrait(CompilerFeature.LocalFunctions)]
public class CodeGenLocalFunctionTests : CSharpTestBase
{
[Fact]
[WorkItem(472056, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=472056")]
public void Repro472056()
{
var comp = CreateCompilationWithMscorlib46(@"
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var task = WhyYouBreaky(new List<string>());
Console.WriteLine(task.Result);
}
static async Task<string> WhyYouBreaky(List<string> words)
{
await Task.Delay(1);
var word = """"; // moving me before the 'await' will make it work
words.Add(""Oh No!""); // I will crash here :(
return ""Great success!""; // Not so much.
void IDontEvenGetCalled()
{
// commenting out either of these lines will make it work
var a = word;
var b = words[0];
}
}
}
}", options: TestOptions.ReleaseExe);
CompileAndVerify(comp, expectedOutput: "Great success!");
}
[Fact]
public void AsyncStructClosure()
{
var comp = CreateCompilationWithMscorlib46(@"
using System;
using System.Threading.Tasks;
class C
{
static void Main() => M().Wait();
static async Task M()
{
int x = 2;
int y = 3;
int L() => x + y;
Console.WriteLine(L());
await Task.FromResult(false);
}
}", options: TestOptions.ReleaseExe);
var verifier = CompileAndVerify(comp, expectedOutput: "5");
// No field captures
verifier.VerifySynthesizedFields("C.<M>d__1",
"int <>1__state",
"System.Runtime.CompilerServices.AsyncTaskMethodBuilder <>t__builder",
"System.Runtime.CompilerServices.TaskAwaiter<bool> <>u__1");
comp = CreateCompilationWithMscorlib46(@"
using System;
using System.Threading.Tasks;
class C
{
static void Main() => M().Wait();
static async Task M()
{
int x = 2;
int y = 3;
int L() => x + y;
Console.WriteLine(L());
await Task.FromResult(false);
x++;
Console.WriteLine(x);
}
}", options: TestOptions.ReleaseExe);
verifier = CompileAndVerify(comp, expectedOutput: @"5
3");
verifier.VerifySynthesizedFields("C.<M>d__1",
"int <>1__state",
"System.Runtime.CompilerServices.AsyncTaskMethodBuilder <>t__builder",
// Display class capture
"C.<>c__DisplayClass1_0 <>8__1",
"System.Runtime.CompilerServices.TaskAwaiter<bool> <>u__1");
verifier.VerifySynthesizedFields("C.<>c__DisplayClass1_0",
"int x",
"int y");
comp = CreateCompilationWithMscorlib46(@"
using System;
using System.Threading.Tasks;
class C
{
static void Main() => M().Wait();
static async Task M()
{
int x = 2;
int y = 3;
int L() => x + y;
Console.WriteLine(L());
await Task.FromResult(false);
x = 5;
y = 7;
Console.WriteLine(L());
}
}", options: TestOptions.ReleaseExe);
verifier = CompileAndVerify(comp, expectedOutput: @"5
12");
// Nothing captured across await
verifier.VerifySynthesizedFields("C.<M>d__1",
"int <>1__state",
"System.Runtime.CompilerServices.AsyncTaskMethodBuilder <>t__builder",
"System.Runtime.CompilerServices.TaskAwaiter<bool> <>u__1");
}
[Fact]
public void IteratorStructClosure()
{
var verifier = CompileAndVerify(@"
using System;
using System.Collections.Generic;
class C
{
static void Main()
{
foreach (var m in M())
{
Console.WriteLine(m);
}
}
static IEnumerable<int> M()
{
int x = 2;
int y = 3;
int L() => x + y;
yield return L();
}
}", expectedOutput: "5");
// No field captures
verifier.VerifySynthesizedFields("C.<M>d__1",
"int <>1__state",
"int <>2__current",
"int <>l__initialThreadId");
verifier = CompileAndVerify(@"
using System;
using System.Collections.Generic;
class C
{
static void Main()
{
foreach (var m in M())
{
Console.WriteLine(m);
}
}
static IEnumerable<int> M()
{
int x = 2;
int y = 3;
int L() => x + y;
yield return L();
x++;
yield return x;
}
}", expectedOutput: @"5
3");
verifier.VerifySynthesizedFields("C.<M>d__1",
"int <>1__state",
"int <>2__current",
"int <>l__initialThreadId",
// Display class capture
"C.<>c__DisplayClass1_0 <>8__1");
verifier.VerifySynthesizedFields("C.<>c__DisplayClass1_0",
"int x",
"int y");
verifier = CompileAndVerify(@"
using System;
using System.Collections.Generic;
class C
{
static void Main()
{
foreach (var m in M())
{
Console.WriteLine(m);
}
}
static IEnumerable<int> M()
{
int x = 2;
int y = 3;
int L() => x + y;
yield return L();
x = 5;
y = 7;
yield return L();
}
}", expectedOutput: @"5
12");
// No captures
verifier.VerifySynthesizedFields("C.<M>d__1",
"int <>1__state",
"int <>2__current",
"int <>l__initialThreadId");
}
[Fact]
[WorkItem(21409, "https://github.com/dotnet/roslyn/issues/21409")]
public void Repro21409()
{
CompileAndVerify(
@"
using System;
using System.Collections.Generic;
namespace Buggles
{
class Program
{
private static IEnumerable<int> Problem(IEnumerable<int> chunks)
{
var startOfChunk = 0;
var pendingChunks = new List<int>();
int GenerateChunk()
{
if (pendingChunks == null)
{
Console.WriteLine(""impossible in local function"");
return -1;
}
while (pendingChunks.Count > 0)
{
pendingChunks.RemoveAt(0);
}
return startOfChunk;
}
foreach (var chunk in chunks)
{
if (chunk - startOfChunk <= 0)
{
pendingChunks.Insert(0, chunk);
}
else
{
yield return GenerateChunk();
}
startOfChunk = chunk;
if (pendingChunks == null)
{
Console.WriteLine(""impossible in outer function"");
}
else
{
pendingChunks.Insert(0, chunk);
}
}
}
private static void Main()
{
var xs = Problem(new[] { 0, 1, 2, 3 });
foreach (var x in xs)
{
Console.WriteLine(x);
}
}
}
}
", expectedOutput: @"
0
1
2");
}
[Fact]
[WorkItem(294554, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=294554")]
public void ThisOnlyClosureBetweenStructCaptures()
......
......@@ -5513,6 +5513,7 @@ .maxstack 2
");
}
[WorkItem(18871, "https://github.com/dotnet/roslyn/issues/18871")]
[WorkItem(546750, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546750")]
[Fact]
public void NumericAdditionChecked_SizeOne()
......@@ -5536,6 +5537,25 @@ void Test(int i, uint u, long l, ulong ul)
p = p + u;
p = p + l;
p = p + ul;
p = p + (-2);
}
}
void Test1(int i, uint u, long l, ulong ul)
{
checked
{
byte b = 3;
byte* p = &b;
p = p - 2;
p = p - 3u;
p = p - 4l;
p = p - 5ul;
p = p - i;
p = p - u;
p = p - l;
p = p - ul;
p = p - (-1);
}
}
}
......@@ -5543,9 +5563,11 @@ void Test(int i, uint u, long l, ulong ul)
// NOTE: even when not optimized.
// NOTE: additional conversions applied to constants of type int and uint.
// NOTE: identical to unchecked except "add" becomes "add.ovf.un".
CompileAndVerify(text, options: TestOptions.UnsafeDebugDll).VerifyIL("C.Test", @"
var comp = CompileAndVerify(text, options: TestOptions.UnsafeDebugDll);
comp.VerifyIL("C.Test", @"
{
// Code size 50 (0x32)
// Code size 57 (0x39)
.maxstack 2
.locals init (byte V_0, //b
byte* V_1) //p
......@@ -5578,28 +5600,191 @@ .maxstack 2
IL_001b: stloc.1
IL_001c: ldloc.1
IL_001d: ldarg.1
IL_001e: add.ovf.un
IL_001f: stloc.1
IL_0020: ldloc.1
IL_0021: ldarg.2
IL_0022: conv.u
IL_0023: add.ovf.un
IL_0024: stloc.1
IL_0025: ldloc.1
IL_0026: ldarg.3
IL_0027: conv.i
IL_0028: add.ovf.un
IL_0029: stloc.1
IL_002a: ldloc.1
IL_002b: ldarg.s V_4
IL_002d: conv.u
IL_002e: add.ovf.un
IL_002f: stloc.1
IL_0030: nop
IL_0031: ret
IL_001e: conv.i
IL_001f: add.ovf.un
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: ldarg.2
IL_0023: conv.u
IL_0024: add.ovf.un
IL_0025: stloc.1
IL_0026: ldloc.1
IL_0027: ldarg.3
IL_0028: conv.i
IL_0029: add.ovf.un
IL_002a: stloc.1
IL_002b: ldloc.1
IL_002c: ldarg.s V_4
IL_002e: conv.u
IL_002f: add.ovf.un
IL_0030: stloc.1
IL_0031: ldloc.1
IL_0032: ldc.i4.s -2
IL_0034: conv.i
IL_0035: add.ovf.un
IL_0036: stloc.1
IL_0037: nop
IL_0038: ret
}");
comp.VerifyIL("C.Test1", @"
{
// Code size 56 (0x38)
.maxstack 2
.locals init (byte V_0, //b
byte* V_1) //p
IL_0000: nop
IL_0001: nop
IL_0002: ldc.i4.3
IL_0003: stloc.0
IL_0004: ldloca.s V_0
IL_0006: conv.u
IL_0007: stloc.1
IL_0008: ldloc.1
IL_0009: ldc.i4.2
IL_000a: sub.ovf.un
IL_000b: stloc.1
IL_000c: ldloc.1
IL_000d: ldc.i4.3
IL_000e: sub.ovf.un
IL_000f: stloc.1
IL_0010: ldloc.1
IL_0011: ldc.i4.4
IL_0012: conv.i8
IL_0013: conv.i
IL_0014: sub.ovf.un
IL_0015: stloc.1
IL_0016: ldloc.1
IL_0017: ldc.i4.5
IL_0018: conv.i8
IL_0019: conv.u
IL_001a: sub.ovf.un
IL_001b: stloc.1
IL_001c: ldloc.1
IL_001d: ldarg.1
IL_001e: conv.i
IL_001f: sub.ovf.un
IL_0020: stloc.1
IL_0021: ldloc.1
IL_0022: ldarg.2
IL_0023: conv.u
IL_0024: sub.ovf.un
IL_0025: stloc.1
IL_0026: ldloc.1
IL_0027: ldarg.3
IL_0028: conv.i
IL_0029: sub.ovf.un
IL_002a: stloc.1
IL_002b: ldloc.1
IL_002c: ldarg.s V_4
IL_002e: conv.u
IL_002f: sub.ovf.un
IL_0030: stloc.1
IL_0031: ldloc.1
IL_0032: ldc.i4.m1
IL_0033: conv.i
IL_0034: sub.ovf.un
IL_0035: stloc.1
IL_0036: nop
IL_0037: ret
}");
}
[Fact]
public void CheckedSignExtend()
{
var text = @"
using System;
unsafe struct S
{
static void Main()
{
byte* ptr1 = default(byte*);
ptr1 = (byte*)2;
checked
{
// should not overflow regardless of 32/64 bit
ptr1 = ptr1 + 2147483649;
}
Console.WriteLine((long)ptr1);
byte* ptr = (byte*)2;
try
{
checked
{
int i = -1;
// should overflow regardless of 32/64 bit
ptr = ptr + i;
}
Console.WriteLine((long)ptr);
}
catch (OverflowException)
{
Console.WriteLine(""overflow"");
Console.WriteLine((long)ptr);
}
}
}
";
CompileAndVerify(text, options: TestOptions.UnsafeReleaseExe, expectedOutput: @"2147483651
overflow
2").VerifyIL("S.Main", @"
{
// Code size 67 (0x43)
.maxstack 2
.locals init (byte* V_0, //ptr1
byte* V_1, //ptr
int V_2) //i
IL_0000: ldloca.s V_0
IL_0002: initobj ""byte*""
IL_0008: ldc.i4.2
IL_0009: conv.i
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: ldc.i4 0x80000001
IL_0011: conv.u
IL_0012: add.ovf.un
IL_0013: stloc.0
IL_0014: ldloc.0
IL_0015: conv.u8
IL_0016: call ""void System.Console.WriteLine(long)""
IL_001b: ldc.i4.2
IL_001c: conv.i
IL_001d: stloc.1
.try
{
IL_001e: ldc.i4.m1
IL_001f: stloc.2
IL_0020: ldloc.1
IL_0021: ldloc.2
IL_0022: conv.i
IL_0023: add.ovf.un
IL_0024: stloc.1
IL_0025: ldloc.1
IL_0026: conv.u8
IL_0027: call ""void System.Console.WriteLine(long)""
IL_002c: leave.s IL_0042
}
catch System.OverflowException
{
IL_002e: pop
IL_002f: ldstr ""overflow""
IL_0034: call ""void System.Console.WriteLine(string)""
IL_0039: ldloc.1
IL_003a: conv.u8
IL_003b: call ""void System.Console.WriteLine(long)""
IL_0040: leave.s IL_0042
}
IL_0042: ret
}
");
}
[Fact]
public void Increment()
{
......
......@@ -7391,7 +7391,7 @@ int Local2(string[] a)
</encLocalSlotMap>
<encLambdaMap>
<methodOrdinal>0</methodOrdinal>
<lambda offset=""99"" />
<lambda offset=""115"" />
<lambda offset=""202"" />
</encLambdaMap>
</customDebugInfo>
......
......@@ -98,6 +98,7 @@ partial class C<T1>
"SymbolDeclaredCompilationEvent(F int C<T1>.F @ : (6,8)-(6,14))",
"SymbolDeclaredCompilationEvent(C C<T1> @ : (2,2)-(8,3), : (9,2)-(12,3))",
"SymbolDeclaredCompilationEvent(M void C<T1>.M(int x1) @ : (4,4)-(4,27))",
"SymbolDeclaredCompilationEvent(M void C<T1>.M(int x2) @ : (11,4)-(11,29))",
"SymbolDeclaredCompilationEvent(N N @ : (0,0)-(13,1))",
"SymbolDeclaredCompilationEvent(<empty> @ : (0,0)-(13,1))",
"SymbolDeclaredCompilationEvent(get_P int C<T1>.P.get @ : (5,21)-(5,25))",
......
......@@ -271,9 +271,15 @@ private static bool DequeueCompilationEvents(AsyncQueue<CompilationEvent> eventQ
{
var symbol = symbolDeclaredEvent.Symbol;
var added = declaredSymbolNames.Add(symbol.Name);
Assert.True(added, "Unexpected multiple symbol declared events for symbol " + symbol);
var method = symbol as Symbols.MethodSymbol;
Assert.Null(method?.PartialDefinitionPart); // we should never get a partial method's implementation part
if (!added)
{
var method = symbol as Symbols.MethodSymbol;
Assert.NotNull(method);
var isPartialMethod = method.PartialDefinitionPart != null ||
method.PartialImplementationPart != null;
Assert.True(isPartialMethod, "Unexpected multiple symbol declared events for symbol " + symbol);
}
}
else
{
......@@ -293,7 +299,7 @@ private static bool DequeueCompilationEvents(AsyncQueue<CompilationEvent> eventQ
public void TestEventQueueCompletionForEmptyCompilation()
{
var compilation = CreateCompilationWithMscorlib45(SpecializedCollections.EmptyEnumerable<SyntaxTree>()).WithEventQueue(new AsyncQueue<CompilationEvent>());
// Force complete compilation event queue
var unused = compilation.GetDiagnostics();
......
// 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 Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public partial class IOperationTests : SemanticModelTestBase
{
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void IConditionalAccessExpression_SimpleMethodAccess()
{
string source = @"
using System;
public class C1
{
public void M()
{
var o = new object();
/*<bind>*/o?.ToString()/*</bind>*/;
}
}
";
string expectedOperationTree = @"
IConditionalAccessExpression (OperationKind.ConditionalAccessExpression, Type: System.String) (Syntax: 'o?.ToString()')
Expression: ILocalReferenceExpression: o (OperationKind.LocalReferenceExpression, Type: System.Object) (Syntax: 'o')
WhenNotNull: IInvocationExpression (virtual System.String System.Object.ToString()) (OperationKind.InvocationExpression, Type: System.String) (Syntax: '.ToString()')
Instance Receiver: IConditionalAccessInstanceExpression (OperationKind.ConditionalAccessInstanceExpression, Type: System.Object) (Syntax: 'o')
Arguments(0)
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<ConditionalAccessExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void IConditionalAccessExpression_SimplePropertyAccess()
{
string source = @"
using System;
public class C1
{
int Prop1 { get; }
public void M()
{
C1 c1 = null;
var prop = /*<bind>*/c1?.Prop1/*</bind>*/;
}
}
";
string expectedOperationTree = @"
IConditionalAccessExpression (OperationKind.ConditionalAccessExpression, Type: System.Int32?) (Syntax: 'c1?.Prop1')
Expression: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: C1) (Syntax: 'c1')
WhenNotNull: IPropertyReferenceExpression: System.Int32 C1.Prop1 { get; } (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: '.Prop1')
Instance Receiver: IConditionalAccessInstanceExpression (OperationKind.ConditionalAccessInstanceExpression, Type: C1) (Syntax: 'c1')
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<ConditionalAccessExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
......@@ -227,7 +227,7 @@ void M(dynamic d)
Initializers(1):
ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'X = 0')
Left: IFieldReferenceExpression: System.Int32 C.X (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'X')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'X')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'X')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
";
var expectedDiagnostics = DiagnosticDescription.None;
......@@ -277,7 +277,7 @@ void M(dynamic d)
Initializers(1):
ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'X = 0')
Left: IFieldReferenceExpression: System.Int32 C.X (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'X')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'X')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'X')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 0) (Syntax: '0')
";
var expectedDiagnostics = DiagnosticDescription.None;
......
......@@ -39,7 +39,7 @@ void M()
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (OperationKind.EventReferenceExpression, Type: System.EventHandler) (Syntax: 't.MyEvent')
Instance Receiver: ILocalReferenceExpression: t (OperationKind.LocalReferenceExpression, Type: Test) (Syntax: 't')
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
";
var expectedDiagnostics = new[] {
// file.cs(6,31): warning CS0067: The event 'Test.MyEvent' is never used
......@@ -117,7 +117,7 @@ void M()
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (Static) (OperationKind.EventReferenceExpression, Type: System.EventHandler) (Syntax: 'Test.MyEvent')
Instance Receiver: null
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
";
var expectedDiagnostics = new[] {
// file.cs(6,38): warning CS0067: The event 'Test.MyEvent' is never used
......@@ -157,7 +157,7 @@ void M()
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (Static) (OperationKind.EventReferenceExpression, Type: System.EventHandler) (Syntax: 'Test.MyEvent')
Instance Receiver: null
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
";
var expectedDiagnostics = new[] {
// file.cs(6,38): warning CS0067: The event 'Test.MyEvent' is never used
......@@ -243,7 +243,7 @@ void M()
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (Static) (OperationKind.EventReferenceExpression, Type: System.EventHandler, IsInvalid) (Syntax: 't.MyEvent')
Instance Receiver: null
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
";
var expectedDiagnostics = new[] {
// file.cs(18,19): error CS0176: Member 'Test.MyEvent' cannot be accessed with an instance reference; qualify it with a type name instead
......@@ -287,7 +287,8 @@ void M()
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (OperationKind.EventReferenceExpression, Type: System.EventHandler, IsInvalid) (Syntax: 'Test.MyEvent')
Instance Receiver: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'Test')
Handler: IMethodBindingExpression: void C.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')";
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C) (Syntax: 'Handler')
";
var expectedDiagnostics = new[] {
// file.cs(17,19): error CS0120: An object reference is required for the non-static field, method, or property 'Test.MyEvent'
// /*<bind>*/Test.MyEvent += Handler/*<bind>*/;
......@@ -324,9 +325,10 @@ void M()
string expectedOperationTree = @"
IEventAssignmentExpression (EventAdd)) (OperationKind.EventAssignmentExpression, Type: System.Void) (Syntax: 'MyEvent += Handler')
Event Reference: IEventReferenceExpression: event System.EventHandler Test.MyEvent (OperationKind.EventReferenceExpression, Type: System.EventHandler) (Syntax: 'MyEvent')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Test) (Syntax: 'MyEvent')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Test) (Syntax: 'MyEvent')
Handler: IMethodBindingExpression: void Test.Handler(System.Object sender, System.EventArgs e) (OperationKind.MethodBindingExpression, Type: System.EventHandler) (Syntax: 'Handler')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Test) (Syntax: 'Handler')";
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Test) (Syntax: 'Handler')
";
var expectedDiagnostics = new[] {
// file.cs(6,31): warning CS0067: The event 'Test.MyEvent' is never used
// public event EventHandler MyEvent;
......
......@@ -186,7 +186,7 @@ static void Main()
Operand: ILocalReferenceExpression: numbers (OperationKind.LocalReferenceExpression, Type: System.Int32[]) (Syntax: 'numbers')
Body: IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IIfStatement (OperationKind.IfStatement) (Syntax: 'if (num>3) ... }')
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'num>3')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'num>3')
Left: ILocalReferenceExpression: num (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'num')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3')
IfTrue: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
......@@ -236,7 +236,7 @@ static void Main()
Operand: ILocalReferenceExpression: numbers (OperationKind.LocalReferenceExpression, Type: System.Int32[]) (Syntax: 'numbers')
Body: IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IIfStatement (OperationKind.IfStatement) (Syntax: 'if (num>3) ... }')
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'num>3')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'num>3')
Left: ILocalReferenceExpression: num (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'num')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3')
IfTrue: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
......@@ -348,8 +348,8 @@ static void Main(string[] args)
Instance Receiver: null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: 'fi.Name + "" ... (employee))')
IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: 'fi.Name + "" ... (employee))')
Left: IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: 'fi.Name + "" = ""')
IBinaryOperatorExpression (BinaryOperatorKind.Add) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: 'fi.Name + "" ... (employee))')
Left: IBinaryOperatorExpression (BinaryOperatorKind.Add) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: 'fi.Name + "" = ""')
Left: IPropertyReferenceExpression: System.String System.Reflection.MemberInfo.Name { get; } (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'fi.Name')
Instance Receiver: ILocalReferenceExpression: fi (OperationKind.LocalReferenceExpression, Type: System.Reflection.FieldInfo) (Syntax: 'fi')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "" = "") (Syntax: '"" = ""')
......@@ -503,7 +503,7 @@ static void Main()
Variables: Local_1: System.Boolean b
Initializer: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Boolean) (Syntax: '!x.Equals(null)')
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IUnaryOperatorExpression (UnaryOperationKind.Invalid) (OperationKind.UnaryOperatorExpression, Type: System.Object) (Syntax: '!x.Equals(null)')
Operand: IUnaryOperatorExpression (UnaryOperatorKind.Not) (OperationKind.UnaryOperatorExpression, Type: System.Object) (Syntax: '!x.Equals(null)')
Operand: IInvocationExpression ( ? C.()) (OperationKind.InvocationExpression, Type: ?) (Syntax: 'x.Equals(null)')
Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'x.Equals')
Arguments(1):
......@@ -592,8 +592,8 @@ void F(int[] a)
Operand: IParameterReferenceExpression: a (OperationKind.ParameterReferenceExpression, Type: System.Int32[]) (Syntax: 'a')
Body: IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: '{ x++; }')
IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid) (Syntax: 'x++;')
Expression: IIncrementExpression (UnaryOperandKind.Invalid) (OperationKind.IncrementExpression, Type: System.Object, IsInvalid) (Syntax: 'x++')
Left: IInvalidExpression (OperationKind.InvalidExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Expression: IIncrementExpression (PostfixIncrement) (OperationKind.IncrementExpression, Type: System.Object, IsInvalid) (Syntax: 'x++')
Target: IInvalidExpression (OperationKind.InvalidExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
Children(1):
ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'x')
NextVariables(0)
......@@ -785,7 +785,7 @@ static void Main(string[] args)
Collection: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: '(IEnumerable)args')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: '(IEnumerable)args')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null)
Operand: IParameterReferenceExpression: args (OperationKind.ParameterReferenceExpression, Type: System.String[]) (Syntax: 'args')
Body: IBlockStatement (0 statements) (OperationKind.BlockStatement) (Syntax: '{ }')
NextVariables(0)
......@@ -825,7 +825,7 @@ static void Main()
Operand: ILocalReferenceExpression: numbers (OperationKind.LocalReferenceExpression, Type: System.Int32[]) (Syntax: 'numbers')
Body: IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
IIfStatement (OperationKind.IfStatement) (Syntax: 'if (num > 3 ... }')
Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'num > 3')
Condition: IBinaryOperatorExpression (BinaryOperatorKind.GreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'num > 3')
Left: ILocalReferenceExpression: num (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'num')
Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3')
IfTrue: IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }')
......
// 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 Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
public partial class IOperationTests : SemanticModelTestBase
{
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void IInstanceReferenceExpression_SimpleBaseReference()
{
string source = @"
using System;
public class C1
{
public virtual void M1() { }
}
public class C2 : C1
{
public override void M1()
{
/*<bind>*/base/*</bind>*/.M1();
}
}
";
string expectedOperationTree = @"
IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: C1) (Syntax: 'base')
";
var expectedDiagnostics = DiagnosticDescription.None;
VerifyOperationTreeAndDiagnosticsForTest<BaseExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
[CompilerTrait(CompilerFeature.IOperation)]
[Fact]
public void IInstanceReferenceExpression_BaseNoMemberReference()
{
string source = @"
using System;
public class C1
{
public virtual void M1()
{
/*<bind>*/base/*</bind>*/.M1();
}
}
";
string expectedOperationTree = @"
IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: System.Object) (Syntax: 'base')
";
var expectedDiagnostics = new DiagnosticDescription[] {
// CS0117: 'object' does not contain a definition for 'M1'
// /*<bind>*/base/*</bind>*/.M1();
Diagnostic(ErrorCode.ERR_NoSuchMember, "M1").WithArguments("object", "M1").WithLocation(8, 35)
};
VerifyOperationTreeAndDiagnosticsForTest<BaseExpressionSyntax>(source, expectedOperationTree, expectedDiagnostics);
}
}
}
......@@ -181,14 +181,14 @@ public void M()
Text: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""String "") (Syntax: 'String ')
IInterpolation (OperationKind.Interpolation) (Syntax: '{x,20}')
Expression: IFieldReferenceExpression: System.String Class.x (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 'x')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'x')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'x')
Alignment: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 20) (Syntax: '20')
FormatString: null
IInterpolatedStringText (OperationKind.InterpolatedStringText) (Syntax: ' and ')
Text: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "" and "") (Syntax: ' and ')
IInterpolation (OperationKind.Interpolation) (Syntax: '{y:D3}')
Expression: IFieldReferenceExpression: System.Int32 Class.y (OperationKind.FieldReferenceExpression, Type: System.Int32) (Syntax: 'y')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'y')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'y')
Alignment: null
FormatString: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""D3"") (Syntax: ':D3')
IInterpolatedStringText (OperationKind.InterpolatedStringText) (Syntax: ' and constant ')
......@@ -228,7 +228,7 @@ public void M()
Text: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""String "") (Syntax: 'String ')
IInterpolation (OperationKind.Interpolation) (Syntax: '{x,y:D3}')
Expression: IFieldReferenceExpression: System.String Class.x (OperationKind.FieldReferenceExpression, Type: System.String) (Syntax: 'x')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'x')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'x')
Alignment: IFieldReferenceExpression: System.Int32 Class.y (Static) (OperationKind.FieldReferenceExpression, Type: System.Int32, Constant: 0) (Syntax: 'y')
Instance Receiver: null
FormatString: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""D3"") (Syntax: ':D3')
......@@ -270,7 +270,7 @@ public void M()
Text: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "" and "") (Syntax: ' and ')
IInterpolation (OperationKind.Interpolation) (Syntax: '{M2(y)}')
Expression: IInvocationExpression ( System.String Class.M2(System.Int32 z)) (OperationKind.InvocationExpression, Type: System.String) (Syntax: 'M2(y)')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'M2')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'M2')
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: z) (OperationKind.Argument) (Syntax: 'y')
ILocalReferenceExpression: y (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'y')
......@@ -316,7 +316,7 @@ public void M()
Text: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""String "") (Syntax: 'String ')
IInterpolation (OperationKind.Interpolation) (Syntax: '{M2($""{y}"")}')
Expression: IInvocationExpression ( System.Int32 Class.M2(System.String z)) (OperationKind.InvocationExpression, Type: System.Int32) (Syntax: 'M2($""{y}"")')
Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'M2')
Instance Receiver: IInstanceReferenceExpression (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'M2')
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: z) (OperationKind.Argument) (Syntax: '$""{y}""')
IInterpolatedStringExpression (OperationKind.InterpolatedStringExpression, Type: System.String) (Syntax: '$""{y}""')
......
......@@ -181,7 +181,7 @@ void M()
Expression: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: System.Int32?) (Syntax: 'x')
Pattern: IConstantPattern (OperationKind.ConstantPattern) (Syntax: '(int)12.0')
Value: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, Constant: 12) (Syntax: '(int)12.0')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: True, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Double, Constant: 12) (Syntax: '12.0')
";
var expectedDiagnostics = DiagnosticDescription.None;
......@@ -437,7 +437,7 @@ void M()
Expression: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'x')
Pattern: IConstantPattern (OperationKind.ConstantPattern, IsInvalid) (Syntax: '')
Value: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) (Syntax: '')
Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Conversion: CommonConversion (Exists: False, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
Operand: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: '')
Children(0)
";
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册