diff --git a/eng/Versions.props b/eng/Versions.props index 3d628323e1bad..22dc4926a7d55 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -94,8 +94,8 @@ 0.8.31-beta 1.0.35 1.4.0 - 1.1.0-beta2-22273-03 - 1.1.0-beta2-22273-03 + 1.1.0-beta2-21528-01 + 1.1.0-beta2-21528-01 17.0.0-beta1.21524.1 1.7.0-beta-21528-01 5.0.0 diff --git a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs index 7eca7f0d035e8..9ae7b2f0ac368 100644 --- a/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs +++ b/src/Compilers/CSharp/Portable/Compiler/MethodCompiler.cs @@ -264,7 +264,6 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul VariableSlotAllocator lazyVariableSlotAllocator = null; var lambdaDebugInfoBuilder = ArrayBuilder.GetInstance(); var closureDebugInfoBuilder = ArrayBuilder.GetInstance(); - var stateMachineStateDebugInfoBuilder = ArrayBuilder.GetInstance(); StateMachineTypeSymbol stateMachineTypeOpt = null; const int methodOrdinal = -1; @@ -281,7 +280,6 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul ref lazyVariableSlotAllocator, lambdaDebugInfoBuilder, closureDebugInfoBuilder, - stateMachineStateDebugInfoBuilder, out stateMachineTypeOpt); Debug.Assert((object)lazyVariableSlotAllocator == null); @@ -289,11 +287,9 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul Debug.Assert(dynamicAnalysisSpans.IsEmpty); Debug.Assert(lambdaDebugInfoBuilder.IsEmpty()); Debug.Assert(closureDebugInfoBuilder.IsEmpty()); - Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty()); lambdaDebugInfoBuilder.Free(); closureDebugInfoBuilder.Free(); - stateMachineStateDebugInfoBuilder.Free(); if (emitMethodBodies) { @@ -304,7 +300,6 @@ private static MethodSymbol GetEntryPoint(CSharpCompilation compilation, PEModul loweredBody, ImmutableArray.Empty, ImmutableArray.Empty, - ImmutableArray.Empty, stateMachineTypeOpt: null, variableSlotAllocatorOpt: null, diagnostics: diagnostics, @@ -704,7 +699,6 @@ private void CompileSynthesizedMethods(TypeCompilationState compilationState) return; } - var stateMachineStateDebugInfoBuilder = ArrayBuilder.GetInstance(); var oldImportChain = compilationState.CurrentImportChain; try { @@ -734,13 +728,13 @@ private void CompileSynthesizedMethods(TypeCompilationState compilationState) { // Local functions can be iterators as well as be async (lambdas can only be async), so we need to lower both iterators and async IteratorStateMachine iteratorStateMachine; - BoundStatement loweredBody = IteratorRewriter.Rewrite(methodWithBody.Body, method, methodOrdinal, stateMachineStateDebugInfoBuilder, variableSlotAllocatorOpt, compilationState, diagnosticsThisMethod, out iteratorStateMachine); + BoundStatement loweredBody = IteratorRewriter.Rewrite(methodWithBody.Body, method, methodOrdinal, variableSlotAllocatorOpt, compilationState, diagnosticsThisMethod, out iteratorStateMachine); StateMachineTypeSymbol stateMachine = iteratorStateMachine; if (!loweredBody.HasErrors) { AsyncStateMachine asyncStateMachine; - loweredBody = AsyncRewriter.Rewrite(loweredBody, method, methodOrdinal, stateMachineStateDebugInfoBuilder, variableSlotAllocatorOpt, compilationState, diagnosticsThisMethod, out asyncStateMachine); + loweredBody = AsyncRewriter.Rewrite(loweredBody, method, methodOrdinal, variableSlotAllocatorOpt, compilationState, diagnosticsThisMethod, out asyncStateMachine); Debug.Assert((object)iteratorStateMachine == null || (object)asyncStateMachine == null); stateMachine = stateMachine ?? asyncStateMachine; @@ -758,7 +752,6 @@ private void CompileSynthesizedMethods(TypeCompilationState compilationState) loweredBody, ImmutableArray.Empty, ImmutableArray.Empty, - stateMachineStateDebugInfoBuilder.ToImmutable(), stateMachine, variableSlotAllocatorOpt, diagnosticsThisMethod, @@ -792,14 +785,11 @@ private void CompileSynthesizedMethods(TypeCompilationState compilationState) { Debug.Assert(emittedBody is null); } - - stateMachineStateDebugInfoBuilder.Clear(); } } finally { compilationState.CurrentImportChain = oldImportChain; - stateMachineStateDebugInfoBuilder.Free(); } } @@ -879,7 +869,6 @@ private void CompileFieldLikeEventAccessor(SourceEventSymbol eventSymbol, bool i boundBody, ImmutableArray.Empty, ImmutableArray.Empty, - ImmutableArray.Empty, stateMachineTypeOpt: null, variableSlotAllocatorOpt: null, diagnostics: diagnosticsThisMethod, @@ -1182,7 +1171,6 @@ forSemanticModel.Syntax is { } semanticModelSyntax && StateMachineTypeSymbol stateMachineTypeOpt = null; var lambdaDebugInfoBuilder = ArrayBuilder.GetInstance(); var closureDebugInfoBuilder = ArrayBuilder.GetInstance(); - var stateMachineStateDebugInfoBuilder = ArrayBuilder.GetInstance(); BoundStatement loweredBodyOpt = null; try @@ -1202,7 +1190,6 @@ forSemanticModel.Syntax is { } semanticModelSyntax && ref lazyVariableSlotAllocator, lambdaDebugInfoBuilder, closureDebugInfoBuilder, - stateMachineStateDebugInfoBuilder, out stateMachineTypeOpt); Debug.Assert(loweredBodyOpt != null); @@ -1255,7 +1242,6 @@ forSemanticModel.Syntax is { } semanticModelSyntax && ref lazyVariableSlotAllocator, lambdaDebugInfoBuilder, closureDebugInfoBuilder, - stateMachineStateDebugInfoBuilder, out initializerStateMachineTypeOpt); processedInitializers.LoweredInitializers = lowered; @@ -1316,7 +1302,6 @@ forSemanticModel.Syntax is { } semanticModelSyntax && boundBody, lambdaDebugInfoBuilder.ToImmutable(), closureDebugInfoBuilder.ToImmutable(), - stateMachineStateDebugInfoBuilder.ToImmutable(), stateMachineTypeOpt, lazyVariableSlotAllocator, diagsForCurrentMethod, @@ -1337,7 +1322,6 @@ forSemanticModel.Syntax is { } semanticModelSyntax && { lambdaDebugInfoBuilder.Free(); closureDebugInfoBuilder.Free(); - stateMachineStateDebugInfoBuilder.Free(); } } finally @@ -1361,7 +1345,6 @@ internal static BoundStatement LowerBodyOrInitializer( ref VariableSlotAllocator lazyVariableSlotAllocator, ArrayBuilder lambdaDebugInfoBuilder, ArrayBuilder closureDebugInfoBuilder, - ArrayBuilder stateMachineStateDebugInfoBuilder, out StateMachineTypeSymbol stateMachineTypeOpt) { Debug.Assert(compilationState.ModuleBuilderOpt != null); @@ -1416,7 +1399,10 @@ internal static BoundStatement LowerBodyOrInitializer( return loweredBody; } - lazyVariableSlotAllocator ??= compilationState.ModuleBuilderOpt.TryCreateVariableSlotAllocator(method, method, diagnostics.DiagnosticBag); + if (lazyVariableSlotAllocator == null) + { + lazyVariableSlotAllocator = compilationState.ModuleBuilderOpt.TryCreateVariableSlotAllocator(method, method, diagnostics.DiagnosticBag); + } BoundStatement bodyWithoutLambdas = loweredBody; if (sawLambdas || sawLocalFunctions) @@ -1441,7 +1427,7 @@ internal static BoundStatement LowerBodyOrInitializer( return bodyWithoutLambdas; } - BoundStatement bodyWithoutIterators = IteratorRewriter.Rewrite(bodyWithoutLambdas, method, methodOrdinal, stateMachineStateDebugInfoBuilder, lazyVariableSlotAllocator, compilationState, diagnostics, + BoundStatement bodyWithoutIterators = IteratorRewriter.Rewrite(bodyWithoutLambdas, method, methodOrdinal, lazyVariableSlotAllocator, compilationState, diagnostics, out IteratorStateMachine iteratorStateMachine); if (bodyWithoutIterators.HasErrors) @@ -1449,7 +1435,7 @@ internal static BoundStatement LowerBodyOrInitializer( return bodyWithoutIterators; } - BoundStatement bodyWithoutAsync = AsyncRewriter.Rewrite(bodyWithoutIterators, method, methodOrdinal, stateMachineStateDebugInfoBuilder, lazyVariableSlotAllocator, compilationState, diagnostics, + BoundStatement bodyWithoutAsync = AsyncRewriter.Rewrite(bodyWithoutIterators, method, methodOrdinal, lazyVariableSlotAllocator, compilationState, diagnostics, out AsyncStateMachine asyncStateMachine); Debug.Assert((object)iteratorStateMachine == null || (object)asyncStateMachine == null); @@ -1474,7 +1460,6 @@ private static MethodBody GenerateMethodBody( BoundStatement block, ImmutableArray lambdaDebugInfo, ImmutableArray closureDebugInfo, - ImmutableArray stateMachineStateDebugInfos, StateMachineTypeSymbol stateMachineTypeOpt, VariableSlotAllocator variableSlotAllocatorOpt, BindingDiagnosticBag diagnostics, @@ -1624,7 +1609,6 @@ private static MethodBody GenerateMethodBody( stateMachineHoistedLocalScopes, stateMachineHoistedLocalSlots, stateMachineAwaiterSlots, - StateMachineStatesDebugInfo.Create(variableSlotAllocatorOpt, stateMachineStateDebugInfos), moveNextBodyDebugInfoOpt, dynamicAnalysisDataOpt); } diff --git a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs index 024eafe5e7b33..893d1b9130241 100644 --- a/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs +++ b/src/Compilers/CSharp/Portable/Emitter/EditAndContinue/CSharpDefinitionMap.cs @@ -192,8 +192,17 @@ protected override ImmutableArray GetLocalSlotMapFromMetadata(Stan return result; } - protected override ITypeSymbolInternal? TryGetStateMachineType(MethodDefinitionHandle methodHandle) - => _metadataDecoder.Module.HasStateMachineAttribute(methodHandle, out var typeName) ? _metadataDecoder.GetTypeSymbolForSerializedType(typeName) : null; + protected override ITypeSymbolInternal? TryGetStateMachineType(EntityHandle methodHandle) + { + string typeName; + if (_metadataDecoder.Module.HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncStateMachineAttribute, out typeName) || + _metadataDecoder.Module.HasStringValuedAttribute(methodHandle, AttributeDescription.IteratorStateMachineAttribute, out typeName)) + { + return _metadataDecoder.GetTypeSymbolForSerializedType(typeName); + } + + return null; + } /// /// Match local declarations to names to generate a map from diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs index d8c903fd0d847..e070c6be33c39 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncExceptionHandlerRewriter.cs @@ -135,7 +135,13 @@ public override BoundNode VisitTryStatement(BoundTryStatement node) var tryStatementSyntax = node.Syntax; // If you add a syntax kind to the assertion below, please also ensure // that the scenario has been tested with Edit-and-Continue. - Debug.Assert(SyntaxBindingUtilities.BindsToTryStatement(tryStatementSyntax)); + Debug.Assert( + tryStatementSyntax.IsKind(SyntaxKind.TryStatement) || + tryStatementSyntax.IsKind(SyntaxKind.UsingStatement) || + tryStatementSyntax.IsKind(SyntaxKind.ForEachStatement) || + tryStatementSyntax.IsKind(SyntaxKind.ForEachVariableStatement) || + tryStatementSyntax.IsKind(SyntaxKind.LocalDeclarationStatement) || + tryStatementSyntax.IsKind(SyntaxKind.LockStatement)); BoundStatement finalizedRegion; BoundBlock rewrittenFinally; @@ -705,7 +711,7 @@ public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatemen private AwaitFinallyFrame PushFrame(BoundTryStatement statement) { - var newFrame = new AwaitFinallyFrame(_currentAwaitFinallyFrame, _analysis.Labels(statement), statement.Syntax); + var newFrame = new AwaitFinallyFrame(_currentAwaitFinallyFrame, _analysis.Labels(statement), (StatementSyntax)statement.Syntax); _currentAwaitFinallyFrame = newFrame; return newFrame; } @@ -884,7 +890,7 @@ private sealed class AwaitFinallyFrame public readonly HashSet LabelsOpt; // the try or using-await statement the frame is associated with - private readonly SyntaxNode _syntaxOpt; + private readonly StatementSyntax _statementSyntaxOpt; // proxy labels for branches leaving the frame. // we build this on demand once we encounter leaving branches. @@ -903,16 +909,20 @@ public AwaitFinallyFrame() // root frame } - public AwaitFinallyFrame(AwaitFinallyFrame parent, HashSet labelsOpt, SyntaxNode syntax) + public AwaitFinallyFrame(AwaitFinallyFrame parent, HashSet labelsOpt, StatementSyntax statementSyntax) { Debug.Assert(parent != null); - Debug.Assert(syntax != null); + Debug.Assert(statementSyntax != null); - Debug.Assert(SyntaxBindingUtilities.BindsToTryStatement(syntax)); + Debug.Assert(statementSyntax.Kind() == SyntaxKind.TryStatement || + (statementSyntax.Kind() == SyntaxKind.UsingStatement && ((UsingStatementSyntax)statementSyntax).AwaitKeyword != default) || + (statementSyntax.Kind() == SyntaxKind.ForEachStatement && ((CommonForEachStatementSyntax)statementSyntax).AwaitKeyword != default) || + (statementSyntax.Kind() == SyntaxKind.ForEachVariableStatement && ((CommonForEachStatementSyntax)statementSyntax).AwaitKeyword != default) || + (statementSyntax.Kind() == SyntaxKind.LocalDeclarationStatement && ((LocalDeclarationStatementSyntax)statementSyntax).AwaitKeyword != default)); this.ParentOpt = parent; this.LabelsOpt = labelsOpt; - _syntaxOpt = syntax; + _statementSyntaxOpt = statementSyntax; } public bool IsRoot() @@ -973,8 +983,8 @@ public LabelSymbol ProxyReturnIfNeeded( returnValue = this.returnValue; if (returnValue == null) { - Debug.Assert(_syntaxOpt != null); - this.returnValue = returnValue = new SynthesizedLocal(containingMethod, TypeWithAnnotations.Create(valueOpt.Type), SynthesizedLocalKind.AsyncMethodReturnValue, _syntaxOpt); + Debug.Assert(_statementSyntaxOpt != null); + this.returnValue = returnValue = new SynthesizedLocal(containingMethod, TypeWithAnnotations.Create(valueOpt.Type), SynthesizedLocalKind.AsyncMethodReturnValue, _statementSyntaxOpt); } } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs index 6a5506952a903..704f12678935d 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncIteratorMethodToStateMachineRewriter.cs @@ -41,9 +41,9 @@ internal sealed class AsyncIteratorMethodToStateMachineRewriter : AsyncMethodToS private readonly LabelSymbol _exprReturnLabelTrue; /// - /// States for `yield return` are decreasing from . + /// States for `yield return` are decreasing from -3. /// - private readonly ResumableStateMachineStateAllocator _iteratorStateAllocator; + private int _nextYieldReturnState = StateMachineStates.InitialAsyncIteratorStateMachine; // -3 internal AsyncIteratorMethodToStateMachineRewriter(MethodSymbol method, int methodOrdinal, @@ -55,40 +55,20 @@ internal AsyncIteratorMethodToStateMachineRewriter(MethodSymbol method, IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) : base(method, methodOrdinal, asyncMethodBuilderMemberCollection, F, state, builder, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, - stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { Debug.Assert(asyncIteratorInfo != null); _asyncIteratorInfo = asyncIteratorInfo; _currentDisposalLabel = _exprReturnLabel; _exprReturnLabelTrue = F.GenerateLabel("yieldReturn"); - - _iteratorStateAllocator = new ResumableStateMachineStateAllocator( - slotAllocatorOpt, - firstState: StateMachineStates.FirstResumableAsyncIteratorState, - increasing: false); } -#nullable enable - protected override BoundStatement? GenerateMissingStateDispatch() - { - var asyncDispatch = base.GenerateMissingStateDispatch(); - - var iteratorDispatch = _iteratorStateAllocator.GenerateThrowMissingStateDispatch(F, F.Local(cachedState), CodeAnalysisResources.EncCannotResumeSuspendedIteratorMethod); - if (iteratorDispatch == null) - { - return asyncDispatch; - } - - return (asyncDispatch != null) ? F.Block(asyncDispatch, iteratorDispatch) : iteratorDispatch; - } -#nullable disable protected override BoundStatement GenerateSetResultCall() { // ... _exprReturnLabel: ... @@ -217,7 +197,7 @@ protected override BoundBinaryOperator ShouldEnterFinallyBlock() // We don't care about state = -2 (method already completed) // So we only want to enter the finally when the state is -1 - return F.IntEqual(F.Local(cachedState), F.Literal(StateMachineStates.NotStartedOrRunningState)); + return F.IntEqual(F.Local(cachedState), F.Literal(StateMachineStates.NotStartedStateMachine)); } #region Visitors @@ -236,7 +216,9 @@ protected override BoundStatement VisitBody(BoundStatement body) // this.state = cachedState = -1; // ... rewritten body - AddState(StateMachineStates.InitialAsyncIteratorState, out GeneratedLabelSymbol resumeLabel); + var initialState = _nextYieldReturnState--; + Debug.Assert(initialState == -3); + AddState(initialState, out GeneratedLabelSymbol resumeLabel); var rewrittenBody = (BoundStatement)Visit(body); @@ -244,7 +226,7 @@ protected override BoundStatement VisitBody(BoundStatement body) return F.Block( F.Label(resumeLabel), // initialStateResumeLabel: GenerateJumpToCurrentDisposalLabel(), // if (disposeMode) goto _exprReturnLabel; - GenerateSetBothStates(StateMachineStates.NotStartedOrRunningState), // this.state = cachedState = -1; + GenerateSetBothStates(StateMachineStates.NotStartedStateMachine), // this.state = cachedState = -1; rewrittenBody); } @@ -263,7 +245,8 @@ public override BoundNode VisitYieldReturnStatement(BoundYieldReturnStatement no // _promiseOfValueOrEnd.SetResult(true); // return; - AddResumableState(_iteratorStateAllocator, node.Syntax, out var stateNumber, out GeneratedLabelSymbol resumeLabel); + var stateNumber = _nextYieldReturnState--; + AddState(stateNumber, out GeneratedLabelSymbol resumeLabel); var rewrittenExpression = (BoundExpression)Visit(node.Expression); var blockBuilder = ArrayBuilder.GetInstance(); @@ -288,7 +271,7 @@ public override BoundNode VisitYieldReturnStatement(BoundYieldReturnStatement no blockBuilder.Add( // this.state = cachedState = NotStartedStateMachine - GenerateSetBothStates(StateMachineStates.NotStartedOrRunningState)); + GenerateSetBothStates(StateMachineStates.NotStartedStateMachine)); Debug.Assert(_currentDisposalLabel is object); // no yield return allowed inside a finally blockBuilder.Add( diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs index 65634991addeb..54d51eeb76004 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncMethodToStateMachineRewriter.cs @@ -74,11 +74,10 @@ internal AsyncMethodToStateMachineRewriter( IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) - : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + : base(F, method, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { _method = method; _asyncMethodBuilderMemberCollection = asyncMethodBuilderMemberCollection; @@ -121,12 +120,6 @@ private FieldSymbol GetAwaiterField(TypeSymbol awaiterType) return result; } - protected sealed override string EncMissingStateMessage - => CodeAnalysisResources.EncCannotResumeSuspendedAsyncMethod; - - protected sealed override int FirstIncreasingResumableState - => StateMachineStates.FirstResumableAsyncState; - /// /// Generate the body for MoveNext(). /// @@ -150,7 +143,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) F.Block(ImmutableArray.Empty, // switch (state) ... F.HiddenSequencePoint(), - Dispatch(isOutermost: true), + Dispatch(), // [body] rewrittenBody ), @@ -161,7 +154,7 @@ internal void GenerateMoveNext(BoundStatement body, MethodSymbol moveNextMethod) bodyBuilder.Add(F.Label(_exprReturnLabel)); // this.state = finishedState - var stateDone = F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedState)); + var stateDone = F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine)); var block = body.Syntax as BlockSyntax; if (block == null) { @@ -235,7 +228,7 @@ protected BoundCatchBlock GenerateExceptionHandling(LocalSymbol exceptionLocal, // _state = finishedState; BoundStatement assignFinishedState = - F.ExpressionStatement(F.AssignmentExpression(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedState))); + F.ExpressionStatement(F.AssignmentExpression(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine))); // builder.SetException(ex); OR if (this.combinedTokens != null) this.combinedTokens.Dispose(); _promiseOfValueOrEnd.SetException(ex); BoundStatement callSetException = GenerateSetExceptionCall(exceptionLocal); @@ -443,7 +436,7 @@ private BoundExpression GenerateGetIsCompleted(LocalSymbol awaiterTemp, MethodSy private BoundBlock GenerateAwaitForIncompleteTask(LocalSymbol awaiterTemp) { - AddResumableState(awaiterTemp.GetDeclaratorSyntax(), out int stateNumber, out GeneratedLabelSymbol resumeLabel); + AddState(out int stateNumber, out GeneratedLabelSymbol resumeLabel); TypeSymbol awaiterFieldType = awaiterTemp.Type.IsVerifierReference() ? F.SpecialType(SpecialType.System_Object) @@ -497,7 +490,7 @@ private BoundBlock GenerateAwaitForIncompleteTask(LocalSymbol awaiterTemp) blockBuilder.Add( // this.state = cachedState = NotStartedStateMachine - GenerateSetBothStates(StateMachineStates.NotStartedOrRunningState)); + GenerateSetBothStates(StateMachineStates.NotStartedStateMachine)); return F.Block(blockBuilder.ToImmutableAndFree()); } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs index d65f85549dbca..e445aec99d928 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncIteratorRewriter.cs @@ -36,11 +36,10 @@ internal AsyncIteratorRewriter( MethodSymbol method, int methodOrdinal, AsyncStateMachine stateMachineType, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) - : base(body, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) + : base(body, method, methodOrdinal, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) { Debug.Assert(!TypeSymbol.Equals(method.IteratorElementTypeWithAnnotations.Type, null, TypeCompareKind.ConsiderEverything2)); @@ -195,7 +194,7 @@ private BoundExpressionStatement GenerateCreateAndAssignBuilder() protected override void InitializeStateMachine(ArrayBuilder bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal) { // var stateMachineLocal = new {StateMachineType}({initialState}) - int initialState = _isEnumerable ? StateMachineStates.FinishedState : StateMachineStates.InitialAsyncIteratorState; + int initialState = _isEnumerable ? StateMachineStates.FinishedStateMachine : StateMachineStates.InitialAsyncIteratorStateMachine; bodyBuilder.Add( F.Assignment( F.Local(stateMachineLocal), @@ -323,7 +322,7 @@ private void GenerateIAsyncEnumeratorImplementation_MoveNextAsync() BoundStatement ifFinished = F.If( // if (state == StateMachineStates.FinishedStateMachine) - F.IntEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.FinishedState)), + F.IntEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.FinishedStateMachine)), // return default; thenClause: F.Return(F.Default(moveNextAsyncReturnType))); @@ -433,13 +432,13 @@ private void GenerateIAsyncDisposable_DisposeAsync() BoundStatement ifInvalidState = F.If( // if (state >= StateMachineStates.NotStartedStateMachine /* -1 */) - F.IntGreaterThanOrEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.NotStartedOrRunningState)), + F.IntGreaterThanOrEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.NotStartedStateMachine)), // throw new NotSupportedException(); thenClause: F.Throw(F.New(F.WellKnownType(WellKnownType.System_NotSupportedException)))); BoundStatement ifFinished = F.If( // if (state == StateMachineStates.FinishedStateMachine) - F.IntEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.FinishedState)), + F.IntEqual(F.InstanceField(stateField), F.Literal(StateMachineStates.FinishedStateMachine)), // return default; thenClause: F.Return(F.Default(returnType))); @@ -651,7 +650,7 @@ private void GenerateIAsyncEnumerableImplementation_GetAsyncEnumerator() .AsMember(IAsyncEnumerableOfElementType); BoundExpression managedThreadId = null; - GenerateIteratorGetEnumerator(IAsyncEnumerableOfElementType_GetEnumerator, ref managedThreadId, initialState: StateMachineStates.InitialAsyncIteratorState); + GenerateIteratorGetEnumerator(IAsyncEnumerableOfElementType_GetEnumerator, ref managedThreadId, initialState: StateMachineStates.InitialAsyncIteratorStateMachine); } protected override void GenerateResetInstance(ArrayBuilder builder, int initialState) @@ -698,7 +697,6 @@ protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNex hoistedVariables: hoistedVariables, nonReusableLocalProxies: nonReusableLocalProxies, synthesizedLocalOrdinals: synthesizedLocalOrdinals, - stateMachineStateDebugInfoBuilder, slotAllocatorOpt: slotAllocatorOpt, nextFreeHoistedLocalSlot: nextFreeHoistedLocalSlot, diagnostics: diagnostics); diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs index 6616076c64846..d26488e5948d7 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AsyncRewriter.cs @@ -25,11 +25,10 @@ private AsyncRewriter( MethodSymbol method, int methodOrdinal, AsyncStateMachine stateMachineType, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) - : base(body, method, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) + : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) { _constructedSuccessfully = AsyncMethodBuilderMemberCollection.TryCreate(F, method, this.stateMachineType.TypeMap, out _asyncMethodBuilderMemberCollection); _methodOrdinal = methodOrdinal; @@ -42,7 +41,6 @@ internal static BoundStatement Rewrite( BoundStatement bodyWithAwaitLifted, MethodSymbol method, int methodOrdinal, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, @@ -75,8 +73,8 @@ internal static BoundStatement Rewrite( compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType); AsyncRewriter rewriter = isAsyncEnumerableOrEnumerator - ? new AsyncIteratorRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) - : new AsyncRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics); + ? new AsyncIteratorRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) + : new AsyncRewriter(bodyWithAwaitLifted, method, methodOrdinal, stateMachineType, slotAllocatorOpt, compilationState, diagnostics); if (!rewriter.VerifyPresenceOfRequiredAPIs()) { @@ -230,7 +228,7 @@ protected override BoundStatement GenerateStateMachineCreation(LocalSymbol state bodyBuilder.Add( F.Assignment( F.Field(F.Local(stateMachineVariable), stateField.AsMember(frameType)), - F.Literal(StateMachineStates.NotStartedOrRunningState))); + F.Literal(StateMachineStates.NotStartedStateMachine))); // local.$builder.Start(ref local) -- binding to the method AsyncTaskMethodBuilder.Start() var startMethod = methodScopeAsyncMethodBuilderMemberCollection.Start.Construct(frameType); @@ -267,7 +265,6 @@ protected virtual void GenerateMoveNext(SynthesizedImplementationMethod moveNext hoistedVariables: hoistedVariables, nonReusableLocalProxies: nonReusableLocalProxies, synthesizedLocalOrdinals: synthesizedLocalOrdinals, - stateMachineStateDebugInfoBuilder, slotAllocatorOpt: slotAllocatorOpt, nextFreeHoistedLocalSlot: nextFreeHoistedLocalSlot, diagnostics: diagnostics); diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.IteratorFinallyFrame.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.IteratorFinallyFrame.cs index 24656238528aa..d1acb500db5af 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.IteratorFinallyFrame.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.IteratorFinallyFrame.cs @@ -57,7 +57,7 @@ public IteratorFinallyFrame( public IteratorFinallyFrame() { - this.finalizeState = StateMachineStates.NotStartedOrRunningState; + this.finalizeState = StateMachineStates.NotStartedStateMachine; } public bool IsRoot() diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs index 2b647596d65c3..8de0bbf1aba92 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorMethodToStateMachineRewriter.cs @@ -53,7 +53,7 @@ internal sealed partial class IteratorMethodToStateMachineRewriter : MethodToSta /// The purpose of distinct finally states is to have enough information about /// which finally handlers must run when we need to finalize iterator after a fault. /// - private int _nextFinalizeState; + private int _nextFinalizeState = StateMachineStates.FinishedStateMachine - 1; // -3 internal IteratorMethodToStateMachineRewriter( SyntheticBoundNodeFactory F, @@ -63,23 +63,14 @@ internal IteratorMethodToStateMachineRewriter( IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) - : base(F, originalMethod, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) + : base(F, originalMethod, state, hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics) { _current = current; - - _nextFinalizeState = slotAllocatorOpt?.GetFirstUnusedStateMachineState(increasing: false) ?? StateMachineStates.FirstIteratorFinalizeState; } - protected override string EncMissingStateMessage - => CodeAnalysisResources.EncCannotResumeSuspendedIteratorMethod; - - protected override int FirstIncreasingResumableState - => StateMachineStates.FirstResumableIteratorState; - internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImplementationMethod moveNextMethod, SynthesizedImplementationMethod disposeMethod) { // scan body for yielding try blocks @@ -95,7 +86,9 @@ internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImpleme /////////////////////////////////// F.CurrentFunction = moveNextMethod; - AddState(StateMachineStates.InitialIteratorState, out GeneratedLabelSymbol initialLabel); + int initialState; + GeneratedLabelSymbol initialLabel; + AddState(out initialState, out initialLabel); var newBody = (BoundStatement)Visit(body); // switch(cachedState) { @@ -115,10 +108,10 @@ internal void GenerateMoveNextAndDispose(BoundStatement body, SynthesizedImpleme F.HiddenSequencePoint(), F.Assignment(F.Local(cachedState), F.Field(F.This(), stateField)), CacheThisIfNeeded(), - Dispatch(isOutermost: true), + Dispatch(), GenerateReturn(finished: true), F.Label(initialLabel), - F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.NotStartedOrRunningState)), + F.Assignment(F.Field(F.This(), stateField), F.Literal(StateMachineStates.NotStartedStateMachine)), newBody); // @@ -328,7 +321,9 @@ public override BoundNode VisitYieldReturnStatement(BoundYieldReturnStatement no // : ; // // this.state = finalizeState; - AddResumableState(node.Syntax, out int stateNumber, out GeneratedLabelSymbol resumeLabel); + int stateNumber; + GeneratedLabelSymbol resumeLabel; + AddState(out stateNumber, out resumeLabel); _currentFinallyFrame.AddState(stateNumber); var rewrittenExpression = (BoundExpression)Visit(node.Expression); @@ -458,18 +453,11 @@ public override BoundNode VisitTryStatement(BoundTryStatement node) private IteratorFinallyFrame PushFrame(BoundTryStatement statement) { - var syntax = statement.Syntax; - - if (slotAllocatorOpt?.TryGetPreviousStateMachineState(syntax, out var finalizeState) != true) - { - finalizeState = _nextFinalizeState--; - } - - AddStateDebugInfo(syntax, finalizeState); + var state = _nextFinalizeState--; - var finallyMethod = MakeSynthesizedFinally(finalizeState); - var newFrame = new IteratorFinallyFrame(_currentFinallyFrame, finalizeState, finallyMethod, _yieldsInTryAnalysis.Labels(statement)); - newFrame.AddState(finalizeState); + var finallyMethod = MakeSynthesizedFinally(state); + var newFrame = new IteratorFinallyFrame(_currentFinallyFrame, state, finallyMethod, _yieldsInTryAnalysis.Labels(statement)); + newFrame.AddState(state); _currentFinallyFrame = newFrame; return newFrame; @@ -486,10 +474,10 @@ private bool ContainsYields(BoundTryStatement statement) return _yieldsInTryAnalysis.ContainsYields(statement); } - private IteratorFinallyMethodSymbol MakeSynthesizedFinally(int finalizeState) + private IteratorFinallyMethodSymbol MakeSynthesizedFinally(int state) { var stateMachineType = (IteratorStateMachine)F.CurrentType; - var finallyMethod = new IteratorFinallyMethodSymbol(stateMachineType, GeneratedNames.MakeIteratorFinallyMethodName(finalizeState)); + var finallyMethod = new IteratorFinallyMethodSymbol(stateMachineType, GeneratedNames.MakeIteratorFinallyMethodName(state)); F.ModuleBuilderOpt.AddSynthesizedDefinition(stateMachineType, finallyMethod.GetCciAdapter()); return finallyMethod; diff --git a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs index a1429a11033e7..4c3ab2c33e4b2 100644 --- a/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/IteratorRewriter/IteratorRewriter.cs @@ -30,11 +30,10 @@ private IteratorRewriter( MethodSymbol method, bool isEnumerable, IteratorStateMachine stateMachineType, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) - : base(body, method, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) + : base(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) { // the element type may contain method type parameters, which are now alpha-renamed into type parameters of the generated class _elementType = stateMachineType.ElementType; @@ -49,7 +48,6 @@ internal static BoundStatement Rewrite( BoundStatement body, MethodSymbol method, int methodOrdinal, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, @@ -82,7 +80,7 @@ internal static BoundStatement Rewrite( stateMachineType = new IteratorStateMachine(slotAllocatorOpt, compilationState, method, methodOrdinal, isEnumerable, elementType); compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType); - var rewriter = new IteratorRewriter(body, method, isEnumerable, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics); + var rewriter = new IteratorRewriter(body, method, isEnumerable, stateMachineType, slotAllocatorOpt, compilationState, diagnostics); if (!rewriter.VerifyPresenceOfRequiredAPIs()) { return body; @@ -250,7 +248,7 @@ private void GenerateEnumerableImplementation(ref BoundExpression managedThreadI var IEnumerableOfElementType_GetEnumerator = F.SpecialMethod(SpecialMember.System_Collections_Generic_IEnumerable_T__GetEnumerator).AsMember(IEnumerableOfElementType); // generate GetEnumerator() - var getEnumeratorGeneric = GenerateIteratorGetEnumerator(IEnumerableOfElementType_GetEnumerator, ref managedThreadId, StateMachineStates.InitialIteratorState); + var getEnumeratorGeneric = GenerateIteratorGetEnumerator(IEnumerableOfElementType_GetEnumerator, ref managedThreadId, StateMachineStates.FirstUnusedState); // Generate IEnumerable.GetEnumerator var getEnumerator = OpenMethodImplementation(IEnumerable_GetEnumerator); @@ -287,7 +285,7 @@ protected override void InitializeStateMachine(ArrayBuilder body { // var stateMachineLocal = new IteratorImplementationClass(N) // where N is either 0 (if we're producing an enumerator) or -2 (if we're producing an enumerable) - int initialState = _isEnumerable ? StateMachineStates.FinishedState : StateMachineStates.InitialIteratorState; + int initialState = _isEnumerable ? StateMachineStates.FinishedStateMachine : StateMachineStates.FirstUnusedState; bodyBuilder.Add( F.Assignment( F.Local(stateMachineLocal), @@ -320,7 +318,6 @@ private void GenerateMoveNextAndDispose( hoistedVariables, nonReusableLocalProxies, synthesizedLocalOrdinals, - stateMachineStateDebugInfoBuilder, slotAllocatorOpt, nextFreeHoistedLocalSlot, diagnostics); diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UsingStatement.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UsingStatement.cs index 41ecea365c121..4a7083be57f42 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UsingStatement.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_UsingStatement.cs @@ -186,7 +186,7 @@ private BoundBlock MakeExpressionUsingStatement(BoundUsingStatement node, BoundB expressionStatement = _instrumenter.InstrumentUsingTargetCapture(node, expressionStatement); } - BoundStatement tryFinally = RewriteUsingStatementTryFinally(usingSyntax, usingSyntax, tryBlock, boundTemp, usingSyntax.AwaitKeyword, node.AwaitOpt, node.PatternDisposeInfoOpt); + BoundStatement tryFinally = RewriteUsingStatementTryFinally(usingSyntax, tryBlock, boundTemp, usingSyntax.AwaitKeyword, node.AwaitOpt, node.PatternDisposeInfoOpt); // { ResourceType temp = expr; try { ... } finally { ... } } return new BoundBlock( @@ -229,7 +229,7 @@ private BoundBlock RewriteDeclarationUsingStatement( if (boundLocal.ConstantValue == ConstantValue.Null) { //localSymbol will be declared by an enclosing block - return BoundBlock.SynthesizedNoLocals(declarationSyntax, rewrittenDeclaration, tryBlock); + return BoundBlock.SynthesizedNoLocals(usingSyntax, rewrittenDeclaration, tryBlock); } if (localType.IsDynamic()) @@ -250,10 +250,10 @@ private BoundBlock RewriteDeclarationUsingStatement( BoundAssignmentOperator tempAssignment; BoundLocal boundTemp = _factory.StoreToTemp(tempInit, out tempAssignment, kind: SynthesizedLocalKind.Using); - BoundStatement tryFinally = RewriteUsingStatementTryFinally(usingSyntax, declarationSyntax, tryBlock, boundTemp, awaitKeywordOpt, awaitOpt, patternDisposeInfo); + BoundStatement tryFinally = RewriteUsingStatementTryFinally(usingSyntax, tryBlock, boundTemp, awaitKeywordOpt, awaitOpt, patternDisposeInfo); return new BoundBlock( - syntax: declarationSyntax, + syntax: usingSyntax, locals: ImmutableArray.Create(boundTemp.LocalSymbol), //localSymbol will be declared by an enclosing block statements: ImmutableArray.Create( rewrittenDeclaration, @@ -262,15 +262,14 @@ private BoundBlock RewriteDeclarationUsingStatement( } else { - BoundStatement tryFinally = RewriteUsingStatementTryFinally(usingSyntax, declarationSyntax, tryBlock, boundLocal, awaitKeywordOpt, awaitOpt, patternDisposeInfo); + BoundStatement tryFinally = RewriteUsingStatementTryFinally(usingSyntax, tryBlock, boundLocal, awaitKeywordOpt, awaitOpt, patternDisposeInfo); // localSymbol will be declared by an enclosing block - return BoundBlock.SynthesizedNoLocals(declarationSyntax, rewrittenDeclaration, tryFinally); + return BoundBlock.SynthesizedNoLocals(usingSyntax, rewrittenDeclaration, tryFinally); } } private BoundStatement RewriteUsingStatementTryFinally( - SyntaxNode typeSyntax, SyntaxNode syntax, BoundBlock tryBlock, BoundLocal local, @@ -353,7 +352,7 @@ private BoundStatement RewriteUsingStatementTryFinally( if (isNullableValueType) { - MethodSymbol getValueOrDefault = UnsafeGetNullableMethod(typeSyntax, local.Type, SpecialMember.System_Nullable_T_GetValueOrDefault); + MethodSymbol getValueOrDefault = UnsafeGetNullableMethod(syntax, local.Type, SpecialMember.System_Nullable_T_GetValueOrDefault); // local.GetValueOrDefault() disposedExpression = BoundCall.Synthesized(syntax, local, getValueOrDefault); } @@ -363,7 +362,7 @@ private BoundStatement RewriteUsingStatementTryFinally( disposedExpression = local; } - BoundExpression disposeCall = GenerateDisposeCall(typeSyntax, syntax, disposedExpression, patternDisposeInfo, awaitOpt, awaitKeywordOpt); + BoundExpression disposeCall = GenerateDisposeCall(syntax, disposedExpression, patternDisposeInfo, awaitOpt, awaitKeywordOpt); // local.Dispose(); or await variant BoundStatement disposeStatement = new BoundExpressionStatement(syntax, disposeCall); @@ -420,7 +419,6 @@ private BoundStatement RewriteUsingStatementTryFinally( } private BoundExpression GenerateDisposeCall( - SyntaxNode typeSyntax, SyntaxNode syntax, BoundExpression disposedExpression, MethodArgumentInfo? disposeInfo, @@ -436,7 +434,7 @@ private BoundExpression GenerateDisposeCall( if (awaitOpt is null) { // IDisposable.Dispose() - Binder.TryGetSpecialTypeMember(_compilation, SpecialMember.System_IDisposable__Dispose, typeSyntax, _diagnostics, out disposeMethod); + Binder.TryGetSpecialTypeMember(_compilation, SpecialMember.System_IDisposable__Dispose, syntax, _diagnostics, out disposeMethod); } else { diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs index f9920cb65fbc8..b0fb061e344da 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/MethodToStateMachineRewriter.cs @@ -22,6 +22,11 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter { internal readonly MethodSymbol OriginalMethod; + /// + /// Generate return statements from the state machine method body. + /// + protected abstract BoundStatement GenerateReturn(bool finished); + protected readonly SyntheticBoundNodeFactory F; /// @@ -51,10 +56,7 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter /// protected readonly LocalSymbol cachedThis; - /// - /// Allocates resumable states, i.e. states that resume execution of the state machine after await expression or yield return. - /// - private readonly ResumableStateMachineStateAllocator _resumableStateAllocator; + private int _nextState; /// /// For each distinct label, the set of states that need to be dispatched to that label. @@ -88,11 +90,6 @@ internal abstract class MethodToStateMachineRewriter : MethodToClassRewriter private readonly SynthesizedLocalOrdinalsDispenser _synthesizedLocalOrdinals; private int _nextFreeHoistedLocalSlot; - /// - /// EnC support: the rewriter stores debug info for each await/yield in this builder. - /// - private readonly ArrayBuilder _stateDebugInfoBuilder; - // new: public MethodToStateMachineRewriter( SyntheticBoundNodeFactory F, @@ -101,7 +98,6 @@ public MethodToStateMachineRewriter( IReadOnlySet hoistedVariables, IReadOnlyDictionary nonReusableLocalProxies, SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, int nextFreeHoistedLocalSlot, BindingDiagnosticBag diagnostics) @@ -139,27 +135,8 @@ public MethodToStateMachineRewriter( BoundExpression thisProxyReplacement = thisProxy.Replacement(F.Syntax, frameType => F.This()); this.cachedThis = F.SynthesizedLocal(thisProxyReplacement.Type, syntax: F.Syntax, kind: SynthesizedLocalKind.FrameCache); } - - _stateDebugInfoBuilder = stateMachineStateDebugInfoBuilder; - - // Use the first state number that is not used by any previous version of the state machine - // for the first added state that doesn't match any states of the previous state machine. - // Note the initial states of the previous and the current state machine are always the same. - // Note the previous state machine might not have any non-initial states. - _resumableStateAllocator = new ResumableStateMachineStateAllocator( - slotAllocatorOpt, - firstState: FirstIncreasingResumableState, - increasing: true); } - protected abstract int FirstIncreasingResumableState { get; } - protected abstract string EncMissingStateMessage { get; } - - /// - /// Generate return statements from the state machine method body. - /// - protected abstract BoundStatement GenerateReturn(bool finished); - protected override bool NeedsProxy(Symbol localOrParameter) { Debug.Assert(localOrParameter.Kind == SymbolKind.Local || localOrParameter.Kind == SymbolKind.Parameter); @@ -198,66 +175,33 @@ protected override BoundExpression FramePointer(SyntaxNode syntax, NamedTypeSymb F.Syntax = oldSyntax; return result; } -#nullable enable - protected void AddResumableState(SyntaxNode awaitOrYieldReturnSyntax, out int stateNumber, out GeneratedLabelSymbol resumeLabel) - => AddResumableState(_resumableStateAllocator, awaitOrYieldReturnSyntax, out stateNumber, out resumeLabel); - protected void AddResumableState(ResumableStateMachineStateAllocator allocator, SyntaxNode awaitOrYieldReturnSyntax, out int stateNumber, out GeneratedLabelSymbol resumeLabel) + protected void AddState(out int stateNumber, out GeneratedLabelSymbol resumeLabel) { - stateNumber = allocator.AllocateState(awaitOrYieldReturnSyntax); - AddStateDebugInfo(awaitOrYieldReturnSyntax, stateNumber); + stateNumber = _nextState++; AddState(stateNumber, out resumeLabel); } - protected void AddStateDebugInfo(SyntaxNode node, int stateNumber) - { - Debug.Assert(SyntaxBindingUtilities.BindsToResumableStateMachineState(node) || SyntaxBindingUtilities.BindsToTryStatement(node), $"Unexpected syntax: {node.Kind()}"); - - int syntaxOffset = CurrentMethod.CalculateLocalSyntaxOffset(node.SpanStart, node.SyntaxTree); - _stateDebugInfoBuilder.Add(new StateMachineStateDebugInfo(syntaxOffset, stateNumber)); - } - protected void AddState(int stateNumber, out GeneratedLabelSymbol resumeLabel) { - _dispatches ??= new Dictionary>(); + if (_dispatches == null) + { + _dispatches = new Dictionary>(); + } resumeLabel = F.GenerateLabel("stateMachine"); - _dispatches.Add(resumeLabel, new List { stateNumber }); + var states = new List(); + states.Add(stateNumber); + _dispatches.Add(resumeLabel, states); } - /// - /// Generates code that switches over states and jumps to the target labels listed in . - /// - /// - /// If this is the outermost state dispatch switching over all states of the state machine - i.e. not state dispatch generated for a try-block. - /// - protected BoundStatement Dispatch(bool isOutermost) - { - var sections = from kv in _dispatches orderby kv.Value[0] select F.SwitchSection(kv.Value, F.Goto(kv.Key)); - var result = F.Switch(F.Local(cachedState), sections.ToImmutableArray()); - - // Suspension states that were generated for any previous generation of the state machine - // but are not present in the current version (awaits/yields have been deleted) need to be dispatched to a throw expression. - // When an instance of previous version of the state machine is suspended in a state that does not exist anymore - // in the current version dispatch that state to a throw expression. We do not know for sure where to resume in the new version of the method. - // Guessing would likely result in unexpected behavior. Resuming in an incorrect point might result in an execution of code that - // has already been executed or skipping code that initializes some user state. - if (isOutermost) - { - var missingStateDispatch = GenerateMissingStateDispatch(); - if (missingStateDispatch != null) - { - result = F.Block(result, missingStateDispatch); - } - } - - return result; + protected BoundStatement Dispatch() + { + return F.Switch(F.Local(cachedState), + (from kv in _dispatches orderby kv.Value[0] select F.SwitchSection(kv.Value, F.Goto(kv.Key))).ToImmutableArray() + ); } - protected virtual BoundStatement? GenerateMissingStateDispatch() - => _resumableStateAllocator.GenerateThrowMissingStateDispatch(F, F.Local(cachedState), EncMissingStateMessage); - -#nullable disable #if DEBUG public override BoundNode VisitSequence(BoundSequence node) { @@ -831,7 +775,7 @@ public override BoundNode VisitTryStatement(BoundTryStatement node) tryBlock = F.Block( F.HiddenSequencePoint(), - Dispatch(isOutermost: false), + Dispatch(), tryBlock); oldDispatches ??= new Dictionary>(); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/ResumableStateMachineStateAllocator.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/ResumableStateMachineStateAllocator.cs deleted file mode 100644 index edb186992cd70..0000000000000 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/ResumableStateMachineStateAllocator.cs +++ /dev/null @@ -1,95 +0,0 @@ -// 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; -using System.Diagnostics; -using Microsoft.CodeAnalysis.CodeGen; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace Microsoft.CodeAnalysis.CSharp -{ - /// - /// Allocates resumable states, i.e. states that resume execution of the state machine after await expression or yield return. - /// - internal sealed class ResumableStateMachineStateAllocator - { - private readonly VariableSlotAllocator? _slotAllocator; - private readonly bool _increasing; - private readonly int _firstState; - - /// - /// The number of the next generated resumable state (i.e. state that resumes execution of the state machine after await expression or yield return). - /// - private int _nextState; - -#if DEBUG - /// - /// EnC support: states in this state machine that were matched to states of the previous generation state machine. - /// - private BitVector _matchedStates = BitVector.Empty; -#endif - /// - /// EnC support: number of states in this state machine that match states of the previous generation state machine. - /// - private int _matchedStateCount; - - public ResumableStateMachineStateAllocator(VariableSlotAllocator? slotAllocator, int firstState, bool increasing) - { - _increasing = increasing; - _slotAllocator = slotAllocator; - _matchedStateCount = 0; - _firstState = firstState; - _nextState = slotAllocator?.GetFirstUnusedStateMachineState(increasing) ?? firstState; - } - - public int AllocateState(SyntaxNode awaitOrYieldReturnSyntax) - { - Debug.Assert(SyntaxBindingUtilities.BindsToResumableStateMachineState(awaitOrYieldReturnSyntax)); - - int direction = _increasing ? +1 : -1; - - if (_slotAllocator?.TryGetPreviousStateMachineState(awaitOrYieldReturnSyntax, out var stateNumber) == true) - { -#if DEBUG - // two states of the new state machine should not match the same state of the previous machine: - Debug.Assert(!_matchedStates[stateNumber * direction]); - _matchedStates[stateNumber * direction] = true; -#endif - _matchedStateCount++; - } - else - { - stateNumber = _nextState; - _nextState += direction; - } - - return stateNumber; - } - - /// - /// True if any of the states generated for any previous state machine has not been allocated in this version. - /// - public bool HasMissingStates - => _matchedStateCount < Math.Abs((_slotAllocator?.GetFirstUnusedStateMachineState(_increasing) ?? _firstState) - _firstState); - - public BoundStatement? GenerateThrowMissingStateDispatch(SyntheticBoundNodeFactory f, BoundExpression cachedState, string message) - { - if (!HasMissingStates) - { - return null; - } - - return f.If( - f.Binary( - _increasing ? BinaryOperatorKind.IntGreaterThanOrEqual : BinaryOperatorKind.IntLessThanOrEqual, - f.SpecialType(SpecialType.System_Boolean), - cachedState, - f.Literal(_firstState)), - f.Throw( - f.New( - f.WellKnownMethod(WellKnownMember.System_InvalidOperationException__ctorString), - f.StringLiteral(ConstantValue.Create(message))))); - } - } -} diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs index 0ef6f322a3bd2..0616f66995d3a 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.cs @@ -25,7 +25,6 @@ internal abstract class StateMachineRewriter protected readonly SynthesizedContainer stateMachineType; protected readonly VariableSlotAllocator slotAllocatorOpt; protected readonly SynthesizedLocalOrdinalsDispenser synthesizedLocalOrdinals; - protected readonly ArrayBuilder stateMachineStateDebugInfoBuilder; protected FieldSymbol stateField; protected IReadOnlyDictionary nonReusableLocalProxies; @@ -38,7 +37,6 @@ protected StateMachineRewriter( BoundStatement body, MethodSymbol method, SynthesizedContainer stateMachineType, - ArrayBuilder stateMachineStateDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) @@ -49,12 +47,10 @@ protected StateMachineRewriter( Debug.Assert(compilationState != null); Debug.Assert(diagnostics != null); Debug.Assert(diagnostics.DiagnosticBag != null); - Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty()); this.body = body; this.method = method; this.stateMachineType = stateMachineType; - this.stateMachineStateDebugInfoBuilder = stateMachineStateDebugInfoBuilder; this.slotAllocatorOpt = slotAllocatorOpt; this.synthesizedLocalOrdinals = new SynthesizedLocalOrdinalsDispenser(); this.diagnostics = diagnostics; @@ -437,7 +433,7 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy makeIterator = F.If( // if (this.state == -2 && this.initialThreadId == Thread.CurrentThread.ManagedThreadId) condition: F.LogicalAnd( - F.IntEqual(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedState)), + F.IntEqual(F.Field(F.This(), stateField), F.Literal(StateMachineStates.FinishedStateMachine)), F.IntEqual(F.Field(F.This(), initialThreadIdField), managedThreadId)), thenClause: F.Block(thenBuilder.ToImmutableAndFree()), elseClauseOpt: makeIterator); diff --git a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineStates.cs b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineStates.cs index 2f17bf33c8c4b..debc8437de81e 100644 --- a/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineStates.cs +++ b/src/Compilers/CSharp/Portable/Lowering/StateMachineRewriter/StateMachineStates.cs @@ -2,38 +2,17 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +#nullable disable + namespace Microsoft.CodeAnalysis.CSharp { internal static class StateMachineStates { - internal const int FirstIteratorFinalizeState = -3; - - internal const int FinishedState = -2; - internal const int NotStartedOrRunningState = -1; + internal const int FinishedStateMachine = -2; + internal const int NotStartedStateMachine = -1; internal const int FirstUnusedState = 0; - /// - /// First state in async state machine that is used to resume the machine after await. - /// - internal const int FirstResumableAsyncState = 0; - - internal const int InitialIteratorState = 0; - - /// - /// First state in iterator state machine that is used to resume the machine after yield return. - /// Initial state is not used to resume state machine that yielded. - /// - internal const int FirstResumableIteratorState = InitialIteratorState + 1; - - /// - /// Used for async-iterators to distinguish initial state from so that DisposeAsync can throw in latter case. - /// - internal const int InitialAsyncIteratorState = -3; - - /// - /// First state in async iterator state machine that is used to resume the machine after yield return. - /// Initial state is not used to resume state machine that yielded. - /// - internal const int FirstResumableAsyncIteratorState = InitialAsyncIteratorState - 1; + // used for async-iterators to distinguish initial state from running state (-1) so that DisposeAsync can throw in latter case + internal const int InitialAsyncIteratorStateMachine = -3; } } diff --git a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs index 520961b991669..0e80a7df79155 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SyntheticBoundNodeFactory.cs @@ -983,9 +983,7 @@ public BoundStatement Switch(BoundExpression ex, ImmutableArray.GetInstance(); var statements = ArrayBuilder.GetInstance(); statements.Add(null!); // placeholder at statements[0] for the dispatch diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs index cf9acb4bcd6e0..bb89a163099c0 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/GeneratedNames.cs @@ -26,14 +26,16 @@ internal static string MakeBackingFieldName(string propertyName) return "<" + propertyName + ">k__BackingField"; } - internal static string MakeIteratorFinallyMethodName(int finalizeState) - { - Debug.Assert(finalizeState < -2); - - // It is important that the name is only derived from the finalizeState, so that when - // editing method during EnC the Finally methods corresponding to matching states have matching names. + internal static string MakeIteratorFinallyMethodName(int iteratorState) + { + // we can pick any name, but we will try to do + // <>m__Finally1 + // <>m__Finally2 + // <>m__Finally3 + // . . . + // that will roughly match native naming scheme and may also be easier when need to debug. Debug.Assert((char)GeneratedNameKind.IteratorFinallyMethod == 'm'); - return "<>m__Finally" + StringExtensions.GetNumeral(-(finalizeState + 2)); + return "<>m__Finally" + StringExtensions.GetNumeral(Math.Abs(iteratorState + 2)); } internal static string MakeStaticLambdaDisplayClassName(int methodOrdinal, int generation) diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxBindingUtilities.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxBindingUtilities.cs deleted file mode 100644 index 16800dd4ecb8e..0000000000000 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxBindingUtilities.cs +++ /dev/null @@ -1,27 +0,0 @@ -// 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; -using System.Collections.Generic; -using System.Text; - -namespace Microsoft.CodeAnalysis.CSharp.Syntax -{ - internal static class SyntaxBindingUtilities - { - public static bool BindsToResumableStateMachineState(SyntaxNode node) - => node.IsKind(SyntaxKind.YieldReturnStatement) || - node.IsKind(SyntaxKind.AwaitExpression) || - node is CommonForEachStatementSyntax { AwaitKeyword.RawKind: not 0 } - or VariableDeclaratorSyntax { Parent.Parent: UsingStatementSyntax { AwaitKeyword.RawKind: not 0 } or LocalDeclarationStatementSyntax { AwaitKeyword.RawKind: not 0 } } - or UsingStatementSyntax { Expression: not null, AwaitKeyword.RawKind: not 0 }; - - public static bool BindsToTryStatement(SyntaxNode node) - => node is VariableDeclaratorSyntax { Parent.Parent: UsingStatementSyntax { } or LocalDeclarationStatementSyntax { UsingKeyword.RawKind: not 0 } } - or UsingStatementSyntax { Expression: not null } - or CommonForEachStatementSyntax - or TryStatementSyntax - or LockStatementSyntax; - } -} diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs index 74d72686e20ea..7d612c9e4f045 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs @@ -973,10 +973,6 @@ public static void Main() - - - - diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs index d4349b1c7f0dd..ceecdf8225a84 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncLocalsTests.cs @@ -364,14 +364,6 @@ public async Task M(IDisposable disposable) - - - - - - - - diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinuePdbTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinuePdbTests.cs index 5b12f12413060..76f7d9a55e97e 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinuePdbTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinuePdbTests.cs @@ -23,7 +23,7 @@ public class EditAndContinuePdbTests : EditAndContinueTestBase [MemberData(nameof(ExternalPdbFormats))] public void MethodExtents(DebugInformationFormat format) { - var source0 = MarkedSource(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""1111111111111111111111111111111111111111"" + var source0 = MarkedSource(WithWindowsLineBreaks(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""1111111111111111111111111111111111111111"" using System; public class C @@ -52,9 +52,9 @@ void G() }; } } -", fileName: @"C:\Enc1.cs"); +"), fileName: @"C:\Enc1.cs"); - var source1 = MarkedSource(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""2222222222222222222222222222222222222222"" + var source1 = MarkedSource(WithWindowsLineBreaks(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""2222222222222222222222222222222222222222"" using System; public class C @@ -83,9 +83,9 @@ void G() int E() => 1; } -", fileName: @"C:\Enc1.cs"); +"), fileName: @"C:\Enc1.cs"); - var source2 = MarkedSource(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""3333333333333333333333333333333333333333"" + var source2 = MarkedSource(WithWindowsLineBreaks(@"#pragma checksum ""C:\Enc1.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""3333333333333333333333333333333333333333"" using System; public class C @@ -116,7 +116,7 @@ void G() int B() => 4; } -", fileName: @"C:\Enc1.cs"); +"), fileName: @"C:\Enc1.cs"); var compilation0 = CreateCompilation(source0.Tree, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All), assemblyName: "EncMethodExtents"); var compilation1 = compilation0.WithSource(source1.Tree); diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs index de960ec8f4dac..4db804c90174b 100644 --- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs +++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.cs @@ -345,78 +345,78 @@ static IEnumerable F() var v0 = CompileAndVerify(compilation0); - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - diff1.VerifySynthesizedMembers( - "C: {d__0#1}", - "C.d__0#1: {<>1__state, <>2__current, <>l__initialThreadId, System.IDisposable.Dispose, MoveNext, System.Collections.Generic.IEnumerator.get_Current, System.Collections.IEnumerator.Reset, System.Collections.IEnumerator.get_Current, System.Collections.Generic.IEnumerable.GetEnumerator, System.Collections.IEnumerable.GetEnumerator, System.Collections.Generic.IEnumerator.Current, System.Collections.IEnumerator.Current}"); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); - using var md1 = diff1.GetMetadata(); - CheckEncLogDefinitions(md1.Reader, - Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.Default), - Row(1, TableIndex.PropertyMap, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(2, TableIndex.Field, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(3, TableIndex.Field, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(4, TableIndex.Field, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(7, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.PropertyMap, EditAndContinueOperation.AddProperty), - Row(1, TableIndex.Property, EditAndContinueOperation.Default), - Row(1, TableIndex.PropertyMap, EditAndContinueOperation.AddProperty), - Row(2, TableIndex.Property, EditAndContinueOperation.Default), - Row(3, TableIndex.MethodDef, EditAndContinueOperation.AddParameter), - Row(1, TableIndex.Param, EditAndContinueOperation.Default), - Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(8, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(12, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodSemantics, EditAndContinueOperation.Default), - Row(2, TableIndex.MethodSemantics, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(2, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(3, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(4, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(6, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(7, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(2, TableIndex.NestedClass, EditAndContinueOperation.Default), - Row(1, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), - Row(2, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), - Row(3, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), - Row(4, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), - Row(5, TableIndex.InterfaceImpl, EditAndContinueOperation.Default)); + using (var md1 = diff1.GetMetadata()) + { + CheckEncLogDefinitions(md1.Reader, + Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.Default), + Row(1, TableIndex.PropertyMap, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(2, TableIndex.Field, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(3, TableIndex.Field, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(4, TableIndex.Field, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(7, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(8, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(10, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.PropertyMap, EditAndContinueOperation.AddProperty), + Row(1, TableIndex.Property, EditAndContinueOperation.Default), + Row(1, TableIndex.PropertyMap, EditAndContinueOperation.AddProperty), + Row(2, TableIndex.Property, EditAndContinueOperation.Default), + Row(3, TableIndex.MethodDef, EditAndContinueOperation.AddParameter), + Row(1, TableIndex.Param, EditAndContinueOperation.Default), + Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(8, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(12, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodSemantics, EditAndContinueOperation.Default), + Row(2, TableIndex.MethodSemantics, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(2, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(3, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(4, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(6, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(7, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(2, TableIndex.NestedClass, EditAndContinueOperation.Default), + Row(1, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), + Row(2, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), + Row(3, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), + Row(4, TableIndex.InterfaceImpl, EditAndContinueOperation.Default), + Row(5, TableIndex.InterfaceImpl, EditAndContinueOperation.Default)); + } + } } [Fact] @@ -447,49 +447,49 @@ static async Task F() var v0 = CompileAndVerify(compilation0); - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - diff1.VerifySynthesizedMembers( - "C.d__0#1: {<>1__state, <>t__builder, <>s__1, <>u__1, MoveNext, SetStateMachine}", - "C: {d__0#1}"); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); - using var md1 = diff1.GetMetadata(); - CheckEncLogDefinitions(md1.Reader, - Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(1, TableIndex.Field, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(2, TableIndex.Field, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(3, TableIndex.Field, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(4, TableIndex.Field, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.AddParameter), - Row(1, TableIndex.Param, EditAndContinueOperation.Default), - Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(2, TableIndex.MethodImpl, EditAndContinueOperation.Default), - Row(1, TableIndex.NestedClass, EditAndContinueOperation.Default), - Row(1, TableIndex.InterfaceImpl, EditAndContinueOperation.Default)); + using (var md1 = diff1.GetMetadata()) + { + CheckEncLogDefinitions(md1.Reader, + Row(2, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(1, TableIndex.Field, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(2, TableIndex.Field, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(3, TableIndex.Field, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(4, TableIndex.Field, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddMethod), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.AddParameter), + Row(1, TableIndex.Param, EditAndContinueOperation.Default), + Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(2, TableIndex.MethodImpl, EditAndContinueOperation.Default), + Row(1, TableIndex.NestedClass, EditAndContinueOperation.Default), + Row(1, TableIndex.InterfaceImpl, EditAndContinueOperation.Default)); + } + } } [Fact] @@ -571,26 +571,28 @@ static Task F() var v0 = CompileAndVerify(compilation0); - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1))); - using (var md1 = diff1.GetMetadata()) - { - CheckAttributes(md1.Reader, - new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // row id 0 == delete - new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef))); // row id 0 == delete - - CheckEncLogDefinitions(md1.Reader, - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), // Delete AsyncStateMachineAttribute - Row(2, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); // Delete DebuggerStepThroughAttribute + using (var md1 = diff1.GetMetadata()) + { + CheckAttributes(md1.Reader, + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef)), // row id 0 == delete + new CustomAttributeRow(Handle(0, TableIndex.MethodDef), Handle(0, TableIndex.MemberRef))); // row id 0 == delete + + CheckEncLogDefinitions(md1.Reader, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), // Delete AsyncStateMachineAttribute + Row(2, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); // Delete DebuggerStepThroughAttribute + } } } @@ -642,50 +644,53 @@ static async Task F(int a) var v0 = CompileAndVerify(compilation0); - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var methodShort0 = compilation0.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int16 a)"); - var methodShort1 = compilation1.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int16 a)"); - - var methodInt0 = compilation0.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int32 a)"); - var methodInt1 = compilation1.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int32 a)"); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var methodShort0 = compilation0.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int16 a)"); + var methodShort1 = compilation1.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int16 a)"); - var methodLong0 = compilation0.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int64 a)"); - var methodLong1 = compilation1.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int64 a)"); + var methodInt0 = compilation0.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int32 a)"); + var methodInt1 = compilation1.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int32 a)"); - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, methodShort0, methodShort1, preserveLocalVariables: true), - SemanticEdit.Create(SemanticEditKind.Update, methodInt0, methodInt1, preserveLocalVariables: true), - SemanticEdit.Create(SemanticEditKind.Update, methodLong0, methodLong1, preserveLocalVariables: true) - )); + var methodLong0 = compilation0.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int64 a)"); + var methodLong1 = compilation1.GetMembers("C.F").Single(m => m.ToTestDisplayString() == "System.Threading.Tasks.Task C.F(System.Int64 a)"); - using var md1 = diff1.GetMetadata(); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, EmptyLocalsProvider); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create( + SemanticEdit.Create(SemanticEditKind.Update, methodShort0, methodShort1, preserveLocalVariables: true), + SemanticEdit.Create(SemanticEditKind.Update, methodInt0, methodInt1, preserveLocalVariables: true), + SemanticEdit.Create(SemanticEditKind.Update, methodLong0, methodLong1, preserveLocalVariables: true) + )); - // notice no TypeDefs, FieldDefs - CheckEncLogDefinitions(md1.Reader, - Row(7, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(8, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(9, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(10, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(11, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(12, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.Param, EditAndContinueOperation.Default), - Row(2, TableIndex.Param, EditAndContinueOperation.Default), - Row(3, TableIndex.Param, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(2, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(8, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); + using (var md1 = diff1.GetMetadata()) + { + // notice no TypeDefs, FieldDefs + CheckEncLogDefinitions(md1.Reader, + Row(7, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(8, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(9, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(10, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(11, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(12, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default), + Row(2, TableIndex.Param, EditAndContinueOperation.Default), + Row(3, TableIndex.Param, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(2, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(8, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); + } + } } [Fact] @@ -1094,5015 +1099,715 @@ .locals init (int V_0, } [Fact] - public void UpdateAsync_Await_Add() + public void UpdateIterator_UserDefinedVariables_NoChange() { - var source0 = MarkedSource(@" -using System.Threading.Tasks; + var source0 = @" +using System.Collections.Generic; class C { - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() + static IEnumerable F(int p) { - await M1(); - await M2(); - End(); + int x = p; + yield return 1; } -}"); - var source1 = MarkedSource(@" -using System.Threading.Tasks; +}"; + var source1 = @" +using System.Collections.Generic; class C { - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() + static IEnumerable F(int p) { - await M1(); - await M3(); - await M2(); - End(); + int x = p; + yield return 2; } -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); +}"; + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll); + var compilation1 = compilation0.WithSource(source1); var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); + var symReader = v0.CreateSymReader(); - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetEquivalentNodesMap(method1, method0), preserveLocalVariables: true))); - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - -"); - v0.VerifyPdb("C+d__4.MoveNext", @" - - - - - - - - - - - - - - - - - - - - - - - - -", options: PdbValidationOptions.ExcludeSequencePoints); + // Verify delta metadata contains expected rows. + using (var md1 = diff1.GetMetadata()) + { + // Verify that no new TypeDefs, FieldDefs or MethodDefs were added, + // 3 methods were updated: + // - the kick-off method (might be changed if the method previously wasn't an iterator) + // - Finally method + // - MoveNext method + CheckEncLogDefinitions(md1.Reader, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - v0.VerifyIL("C.d__4.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" + diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" { - // Code size 268 (0x10c) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__4 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__4.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0019 - IL_0012: br.s IL_0055 - IL_0014: br IL_00b1 - - IL_0019: nop - IL_001a: call ""System.Threading.Tasks.Task C.M1()"" - IL_001f: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0024: stloc.1 - IL_0025: ldloca.s V_1 - IL_0027: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_002c: brtrue.s IL_0071 - - IL_002e: ldarg.0 - IL_002f: ldc.i4.0 - IL_0030: dup - IL_0031: stloc.0 - IL_0032: stfld ""int C.d__4.<>1__state"" - IL_0037: ldarg.0 - IL_0038: ldloc.1 - IL_0039: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_003e: ldarg.0 - IL_003f: stloc.2 - IL_0040: ldarg.0 - IL_0041: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0046: ldloca.s V_1 - IL_0048: ldloca.s V_2 - IL_004a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_004f: nop - IL_0050: leave IL_010b - - IL_0055: ldarg.0 - IL_0056: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_005b: stloc.1 - IL_005c: ldarg.0 - IL_005d: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0062: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0068: ldarg.0 - IL_0069: ldc.i4.m1 - IL_006a: dup - IL_006b: stloc.0 - IL_006c: stfld ""int C.d__4.<>1__state"" - - IL_0071: ldloca.s V_1 - IL_0073: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0078: nop - IL_0079: call ""System.Threading.Tasks.Task C.M2()"" - IL_007e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0083: stloc.3 - IL_0084: ldloca.s V_3 - IL_0086: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_008b: brtrue.s IL_00cd - - IL_008d: ldarg.0 - IL_008e: ldc.i4.1 - IL_008f: dup - IL_0090: stloc.0 - IL_0091: stfld ""int C.d__4.<>1__state"" - IL_0096: ldarg.0 - IL_0097: ldloc.3 - IL_0098: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_009d: ldarg.0 - IL_009e: stloc.2 - IL_009f: ldarg.0 - IL_00a0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00a5: ldloca.s V_3 - IL_00a7: ldloca.s V_2 - IL_00a9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_00ae: nop - IL_00af: leave.s IL_010b - - IL_00b1: ldarg.0 - IL_00b2: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00b7: stloc.3 - IL_00b8: ldarg.0 - IL_00b9: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00be: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00c4: ldarg.0 - IL_00c5: ldc.i4.m1 - IL_00c6: dup - IL_00c7: stloc.0 - IL_00c8: stfld ""int C.d__4.<>1__state"" - - IL_00cd: ldloca.s V_3 - IL_00cf: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00d4: nop - IL_00d5: call ""void C.End()"" - IL_00da: nop - IL_00db: leave.s IL_00f7 - } - catch System.Exception - { - IL_00dd: stloc.s V_4 - IL_00df: ldarg.0 - IL_00e0: ldc.i4.s -2 - IL_00e2: stfld ""int C.d__4.<>1__state"" - IL_00e7: ldarg.0 - IL_00e8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00ed: ldloc.s V_4 - IL_00ef: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_00f4: nop - IL_00f5: leave.s IL_010b - } - IL_00f7: ldarg.0 - IL_00f8: ldc.i4.s -2 - IL_00fa: stfld ""int C.d__4.<>1__state"" - IL_00ff: ldarg.0 - IL_0100: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0105: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_010a: nop - IL_010b: ret -} -"); - - diff1.VerifyIL("C.d__4.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 380 (0x17c) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__4 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Runtime.CompilerServices.TaskAwaiter V_4, - System.Exception V_5) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__4.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001b, - IL_001d, - IL_0022) - IL_0019: br.s IL_0027 - IL_001b: br.s IL_0063 - IL_001d: br IL_0120 - IL_0022: br IL_00c2 - - IL_0027: nop - IL_0028: call ""System.Threading.Tasks.Task C.M1()"" - IL_002d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0032: stloc.1 - IL_0033: ldloca.s V_1 - IL_0035: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003a: brtrue.s IL_007f - - IL_003c: ldarg.0 - IL_003d: ldc.i4.0 - IL_003e: dup - IL_003f: stloc.0 - IL_0040: stfld ""int C.d__4.<>1__state"" - IL_0045: ldarg.0 - IL_0046: ldloc.1 - IL_0047: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_004c: ldarg.0 - IL_004d: stloc.2 - IL_004e: ldarg.0 - IL_004f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0054: ldloca.s V_1 - IL_0056: ldloca.s V_2 - IL_0058: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_005d: nop - IL_005e: leave IL_017b - - IL_0063: ldarg.0 - IL_0064: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0069: stloc.1 - IL_006a: ldarg.0 - IL_006b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0070: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0076: ldarg.0 - IL_0077: ldc.i4.m1 - IL_0078: dup - IL_0079: stloc.0 - IL_007a: stfld ""int C.d__4.<>1__state"" - - IL_007f: ldloca.s V_1 - IL_0081: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0086: nop - IL_0087: call ""System.Threading.Tasks.Task C.M3()"" - IL_008c: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0091: stloc.3 - IL_0092: ldloca.s V_3 - IL_0094: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0099: brtrue.s IL_00de - - IL_009b: ldarg.0 - IL_009c: ldc.i4.2 - IL_009d: dup - IL_009e: stloc.0 - IL_009f: stfld ""int C.d__4.<>1__state"" - IL_00a4: ldarg.0 - IL_00a5: ldloc.3 - IL_00a6: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00ab: ldarg.0 - IL_00ac: stloc.2 - IL_00ad: ldarg.0 - IL_00ae: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00b3: ldloca.s V_3 - IL_00b5: ldloca.s V_2 - IL_00b7: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_00bc: nop - IL_00bd: leave IL_017b - - IL_00c2: ldarg.0 - IL_00c3: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00c8: stloc.3 - IL_00c9: ldarg.0 - IL_00ca: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00cf: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00d5: ldarg.0 - IL_00d6: ldc.i4.m1 - IL_00d7: dup - IL_00d8: stloc.0 - IL_00d9: stfld ""int C.d__4.<>1__state"" - - IL_00de: ldloca.s V_3 - IL_00e0: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00e5: nop - IL_00e6: call ""System.Threading.Tasks.Task C.M2()"" - IL_00eb: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_00f0: stloc.s V_4 - IL_00f2: ldloca.s V_4 - IL_00f4: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_00f9: brtrue.s IL_013d - - IL_00fb: ldarg.0 - IL_00fc: ldc.i4.1 - IL_00fd: dup - IL_00fe: stloc.0 - IL_00ff: stfld ""int C.d__4.<>1__state"" - IL_0104: ldarg.0 - IL_0105: ldloc.s V_4 - IL_0107: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_010c: ldarg.0 - IL_010d: stloc.2 - IL_010e: ldarg.0 - IL_010f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0114: ldloca.s V_4 - IL_0116: ldloca.s V_2 - IL_0118: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_011d: nop - IL_011e: leave.s IL_017b - - IL_0120: ldarg.0 - IL_0121: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0126: stloc.s V_4 - IL_0128: ldarg.0 - IL_0129: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_012e: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0134: ldarg.0 - IL_0135: ldc.i4.m1 - IL_0136: dup - IL_0137: stloc.0 - IL_0138: stfld ""int C.d__4.<>1__state"" - - IL_013d: ldloca.s V_4 - IL_013f: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0144: nop - IL_0145: call ""void C.End()"" - IL_014a: nop - IL_014b: leave.s IL_0167 - } - catch System.Exception - { - IL_014d: stloc.s V_5 - IL_014f: ldarg.0 - IL_0150: ldc.i4.s -2 - IL_0152: stfld ""int C.d__4.<>1__state"" - IL_0157: ldarg.0 - IL_0158: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_015d: ldloc.s V_5 - IL_015f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0164: nop - IL_0165: leave.s IL_017b - } - IL_0167: ldarg.0 - IL_0168: ldc.i4.s -2 - IL_016a: stfld ""int C.d__4.<>1__state"" - IL_016f: ldarg.0 - IL_0170: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0175: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_017a: nop - IL_017b: ret -} -"); - } - - [Fact] - public void UpdateAsync_Await_Remove_RemoveAdd() - { - var source0 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() - { - await M1(); - await M3(); - await M2(); - End(); - } -}"); - var source1 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() - { - await M1(); - await M2(); - End(); - } -}"); - var source2 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() - { - await M3(); - await M1(); - End(); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - var compilation2 = compilation0.WithSource(source2.Tree); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - var f2 = compilation2.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - var diff2 = compilation2.EmitDifference( - diff1.NextGeneration, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f1, f2, GetSyntaxMapFromMarkers(source1, source2), preserveLocalVariables: true))); - - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - - -"); - v0.VerifyPdb("C+d__4.MoveNext", @" - - - - - - - - - - - - - - - - - - - - - - - - - - -", options: PdbValidationOptions.ExcludeSequencePoints); - - v0.VerifyIL("C.d__4.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 380 (0x17c) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__4 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Runtime.CompilerServices.TaskAwaiter V_4, - System.Exception V_5) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__4.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001b, - IL_001d, - IL_0022) - IL_0019: br.s IL_0027 - IL_001b: br.s IL_0063 - IL_001d: br IL_00c2 - IL_0022: br IL_0120 - - IL_0027: nop - IL_0028: call ""System.Threading.Tasks.Task C.M1()"" - IL_002d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0032: stloc.1 - IL_0033: ldloca.s V_1 - IL_0035: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003a: brtrue.s IL_007f - - IL_003c: ldarg.0 - IL_003d: ldc.i4.0 - IL_003e: dup - IL_003f: stloc.0 - IL_0040: stfld ""int C.d__4.<>1__state"" - IL_0045: ldarg.0 - IL_0046: ldloc.1 - IL_0047: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_004c: ldarg.0 - IL_004d: stloc.2 - IL_004e: ldarg.0 - IL_004f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0054: ldloca.s V_1 - IL_0056: ldloca.s V_2 - IL_0058: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_005d: nop - IL_005e: leave IL_017b - - IL_0063: ldarg.0 - IL_0064: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0069: stloc.1 - IL_006a: ldarg.0 - IL_006b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0070: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0076: ldarg.0 - IL_0077: ldc.i4.m1 - IL_0078: dup - IL_0079: stloc.0 - IL_007a: stfld ""int C.d__4.<>1__state"" - - IL_007f: ldloca.s V_1 - IL_0081: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0086: nop - IL_0087: call ""System.Threading.Tasks.Task C.M3()"" - IL_008c: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0091: stloc.3 - IL_0092: ldloca.s V_3 - IL_0094: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0099: brtrue.s IL_00de - - IL_009b: ldarg.0 - IL_009c: ldc.i4.1 - IL_009d: dup - IL_009e: stloc.0 - IL_009f: stfld ""int C.d__4.<>1__state"" - IL_00a4: ldarg.0 - IL_00a5: ldloc.3 - IL_00a6: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00ab: ldarg.0 - IL_00ac: stloc.2 - IL_00ad: ldarg.0 - IL_00ae: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00b3: ldloca.s V_3 - IL_00b5: ldloca.s V_2 - IL_00b7: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_00bc: nop - IL_00bd: leave IL_017b - - IL_00c2: ldarg.0 - IL_00c3: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00c8: stloc.3 - IL_00c9: ldarg.0 - IL_00ca: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00cf: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00d5: ldarg.0 - IL_00d6: ldc.i4.m1 - IL_00d7: dup - IL_00d8: stloc.0 - IL_00d9: stfld ""int C.d__4.<>1__state"" - - IL_00de: ldloca.s V_3 - IL_00e0: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00e5: nop - IL_00e6: call ""System.Threading.Tasks.Task C.M2()"" - IL_00eb: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_00f0: stloc.s V_4 - IL_00f2: ldloca.s V_4 - IL_00f4: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_00f9: brtrue.s IL_013d - - IL_00fb: ldarg.0 - IL_00fc: ldc.i4.2 - IL_00fd: dup - IL_00fe: stloc.0 - IL_00ff: stfld ""int C.d__4.<>1__state"" - IL_0104: ldarg.0 - IL_0105: ldloc.s V_4 - IL_0107: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_010c: ldarg.0 - IL_010d: stloc.2 - IL_010e: ldarg.0 - IL_010f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0114: ldloca.s V_4 - IL_0116: ldloca.s V_2 - IL_0118: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_011d: nop - IL_011e: leave.s IL_017b - - IL_0120: ldarg.0 - IL_0121: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0126: stloc.s V_4 - IL_0128: ldarg.0 - IL_0129: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_012e: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0134: ldarg.0 - IL_0135: ldc.i4.m1 - IL_0136: dup - IL_0137: stloc.0 - IL_0138: stfld ""int C.d__4.<>1__state"" - - IL_013d: ldloca.s V_4 - IL_013f: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0144: nop - IL_0145: call ""void C.End()"" - IL_014a: nop - IL_014b: leave.s IL_0167 - } - catch System.Exception - { - IL_014d: stloc.s V_5 - IL_014f: ldarg.0 - IL_0150: ldc.i4.s -2 - IL_0152: stfld ""int C.d__4.<>1__state"" - IL_0157: ldarg.0 - IL_0158: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_015d: ldloc.s V_5 - IL_015f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0164: nop - IL_0165: leave.s IL_017b - } - IL_0167: ldarg.0 - IL_0168: ldc.i4.s -2 - IL_016a: stfld ""int C.d__4.<>1__state"" - IL_016f: ldarg.0 - IL_0170: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0175: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_017a: nop - IL_017b: ret -} -"); - - diff1.VerifyIL("C.d__4.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 283 (0x11b) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__4 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__4.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.2 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0019 - IL_0012: br.s IL_0064 - IL_0014: br IL_00c0 - IL_0019: ldloc.0 - IL_001a: ldc.i4.0 - IL_001b: blt.s IL_0028 - IL_001d: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedAsyncMethod + @""" - IL_0022: newobj ""System.InvalidOperationException..ctor(string)"" - IL_0027: throw - - IL_0028: nop - IL_0029: call ""System.Threading.Tasks.Task C.M1()"" - IL_002e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0033: stloc.1 - IL_0034: ldloca.s V_1 - IL_0036: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003b: brtrue.s IL_0080 - - IL_003d: ldarg.0 - IL_003e: ldc.i4.0 - IL_003f: dup - IL_0040: stloc.0 - IL_0041: stfld ""int C.d__4.<>1__state"" - IL_0046: ldarg.0 - IL_0047: ldloc.1 - IL_0048: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_004d: ldarg.0 - IL_004e: stloc.2 - IL_004f: ldarg.0 - IL_0050: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0055: ldloca.s V_1 - IL_0057: ldloca.s V_2 - IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_005e: nop - IL_005f: leave IL_011a - - IL_0064: ldarg.0 - IL_0065: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_006a: stloc.1 - IL_006b: ldarg.0 - IL_006c: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0071: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0077: ldarg.0 - IL_0078: ldc.i4.m1 - IL_0079: dup - IL_007a: stloc.0 - IL_007b: stfld ""int C.d__4.<>1__state"" - IL_0080: ldloca.s V_1 - IL_0082: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0087: nop - IL_0088: call ""System.Threading.Tasks.Task C.M2()"" - IL_008d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0092: stloc.3 - IL_0093: ldloca.s V_3 - IL_0095: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_009a: brtrue.s IL_00dc - - IL_009c: ldarg.0 - IL_009d: ldc.i4.2 - IL_009e: dup - IL_009f: stloc.0 - IL_00a0: stfld ""int C.d__4.<>1__state"" - IL_00a5: ldarg.0 - IL_00a6: ldloc.3 - IL_00a7: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00ac: ldarg.0 - IL_00ad: stloc.2 - IL_00ae: ldarg.0 - IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00b4: ldloca.s V_3 - IL_00b6: ldloca.s V_2 - IL_00b8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_00bd: nop - IL_00be: leave.s IL_011a - - IL_00c0: ldarg.0 - IL_00c1: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00c6: stloc.3 - IL_00c7: ldarg.0 - IL_00c8: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00cd: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00d3: ldarg.0 - IL_00d4: ldc.i4.m1 - IL_00d5: dup - IL_00d6: stloc.0 - IL_00d7: stfld ""int C.d__4.<>1__state"" - - IL_00dc: ldloca.s V_3 - IL_00de: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00e3: nop - IL_00e4: call ""void C.End()"" - IL_00e9: nop - IL_00ea: leave.s IL_0106 - } - catch System.Exception - { - IL_00ec: stloc.s V_4 - IL_00ee: ldarg.0 - IL_00ef: ldc.i4.s -2 - IL_00f1: stfld ""int C.d__4.<>1__state"" - IL_00f6: ldarg.0 - IL_00f7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00fc: ldloc.s V_4 - IL_00fe: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0103: nop - IL_0104: leave.s IL_011a - } - IL_0106: ldarg.0 - IL_0107: ldc.i4.s -2 - IL_0109: stfld ""int C.d__4.<>1__state"" - IL_010e: ldarg.0 - IL_010f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0114: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0119: nop - IL_011a: ret -} -"); - // note that CDI is not emitted to the delta since we already have the information captured in changed symbols: - diff1.VerifyPdb(Enumerable.Range(1, 20).Select(MetadataTokens.MethodDefinitionHandle), @" - - - - - - - - - - - - - - - - -"); - diff2.VerifyIL("C.d__4.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 283 (0x11b) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__4 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__4.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.3 - IL_000e: beq.s IL_0017 - IL_0010: br.s IL_0019 - IL_0012: br IL_00c0 - IL_0017: br.s IL_0064 - IL_0019: ldloc.0 - IL_001a: ldc.i4.0 - IL_001b: blt.s IL_0028 - IL_001d: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedAsyncMethod + @""" - IL_0022: newobj ""System.InvalidOperationException..ctor(string)"" - IL_0027: throw - - IL_0028: nop - IL_0029: call ""System.Threading.Tasks.Task C.M3()"" - IL_002e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0033: stloc.1 - IL_0034: ldloca.s V_1 - IL_0036: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003b: brtrue.s IL_0080 - - IL_003d: ldarg.0 - IL_003e: ldc.i4.3 - IL_003f: dup - IL_0040: stloc.0 - IL_0041: stfld ""int C.d__4.<>1__state"" - IL_0046: ldarg.0 - IL_0047: ldloc.1 - IL_0048: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_004d: ldarg.0 - IL_004e: stloc.2 - IL_004f: ldarg.0 - IL_0050: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0055: ldloca.s V_1 - IL_0057: ldloca.s V_2 - IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_005e: nop - IL_005f: leave IL_011a - - IL_0064: ldarg.0 - IL_0065: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_006a: stloc.1 - IL_006b: ldarg.0 - IL_006c: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0071: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0077: ldarg.0 - IL_0078: ldc.i4.m1 - IL_0079: dup - IL_007a: stloc.0 - IL_007b: stfld ""int C.d__4.<>1__state"" - - IL_0080: ldloca.s V_1 - IL_0082: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0087: nop - IL_0088: call ""System.Threading.Tasks.Task C.M1()"" - IL_008d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0092: stloc.3 - IL_0093: ldloca.s V_3 - IL_0095: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_009a: brtrue.s IL_00dc - - IL_009c: ldarg.0 - IL_009d: ldc.i4.0 - IL_009e: dup - IL_009f: stloc.0 - IL_00a0: stfld ""int C.d__4.<>1__state"" - IL_00a5: ldarg.0 - IL_00a6: ldloc.3 - IL_00a7: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00ac: ldarg.0 - IL_00ad: stloc.2 - IL_00ae: ldarg.0 - IL_00af: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00b4: ldloca.s V_3 - IL_00b6: ldloca.s V_2 - IL_00b8: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_00bd: nop - IL_00be: leave.s IL_011a - - IL_00c0: ldarg.0 - IL_00c1: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00c6: stloc.3 - IL_00c7: ldarg.0 - IL_00c8: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_00cd: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00d3: ldarg.0 - IL_00d4: ldc.i4.m1 - IL_00d5: dup - IL_00d6: stloc.0 - IL_00d7: stfld ""int C.d__4.<>1__state"" - - IL_00dc: ldloca.s V_3 - IL_00de: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00e3: nop - IL_00e4: call ""void C.End()"" - IL_00e9: nop - IL_00ea: leave.s IL_0106 - } - catch System.Exception - { - IL_00ec: stloc.s V_4 - IL_00ee: ldarg.0 - IL_00ef: ldc.i4.s -2 - IL_00f1: stfld ""int C.d__4.<>1__state"" - IL_00f6: ldarg.0 - IL_00f7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00fc: ldloc.s V_4 - IL_00fe: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0103: nop - IL_0104: leave.s IL_011a - } - IL_0106: ldarg.0 - IL_0107: ldc.i4.s -2 - IL_0109: stfld ""int C.d__4.<>1__state"" - IL_010e: ldarg.0 - IL_010f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0114: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0119: nop - IL_011a: ret -} -"); - } - - [Fact] - public void UpdateAsync_Await_Remove_FirstAndLast() - { - var source0 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() - { - await M1(); - await M2(); - await M3(); - End(); - } -}"); - var source1 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static void End() {} - - static async Task F() - { - await M2(); - End(); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - diff1.VerifyIL("C.d__4.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 176 (0xb0) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__4 V_2, - System.Exception V_3) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__4.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.1 - IL_0009: beq.s IL_000d - IL_000b: br.s IL_000f - IL_000d: br.s IL_0057 - IL_000f: ldloc.0 - IL_0010: ldc.i4.0 - IL_0011: blt.s IL_001e - IL_0013: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedAsyncMethod + @""" - IL_0018: newobj ""System.InvalidOperationException..ctor(string)"" - IL_001d: throw - - IL_001e: nop - IL_001f: call ""System.Threading.Tasks.Task C.M2()"" - IL_0024: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0029: stloc.1 - IL_002a: ldloca.s V_1 - IL_002c: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0031: brtrue.s IL_0073 - - IL_0033: ldarg.0 - IL_0034: ldc.i4.1 - IL_0035: dup - IL_0036: stloc.0 - IL_0037: stfld ""int C.d__4.<>1__state"" - IL_003c: ldarg.0 - IL_003d: ldloc.1 - IL_003e: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0043: ldarg.0 - IL_0044: stloc.2 - IL_0045: ldarg.0 - IL_0046: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_004b: ldloca.s V_1 - IL_004d: ldloca.s V_2 - IL_004f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__4>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__4)"" - IL_0054: nop - IL_0055: leave.s IL_00af - - IL_0057: ldarg.0 - IL_0058: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_005d: stloc.1 - IL_005e: ldarg.0 - IL_005f: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__4.<>u__1"" - IL_0064: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_006a: ldarg.0 - IL_006b: ldc.i4.m1 - IL_006c: dup - IL_006d: stloc.0 - IL_006e: stfld ""int C.d__4.<>1__state"" - - IL_0073: ldloca.s V_1 - IL_0075: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_007a: nop - IL_007b: call ""void C.End()"" - IL_0080: nop - IL_0081: leave.s IL_009b - } - catch System.Exception - { - IL_0083: stloc.3 - IL_0084: ldarg.0 - IL_0085: ldc.i4.s -2 - IL_0087: stfld ""int C.d__4.<>1__state"" - IL_008c: ldarg.0 - IL_008d: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_0092: ldloc.3 - IL_0093: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0098: nop - IL_0099: leave.s IL_00af - } - IL_009b: ldarg.0 - IL_009c: ldc.i4.s -2 - IL_009e: stfld ""int C.d__4.<>1__state"" - IL_00a3: ldarg.0 - IL_00a4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__4.<>t__builder"" - IL_00a9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_00ae: nop - IL_00af: ret -} -"); - } - - [Fact] - public void UpdateAsync_Await_Remove_TryBlock() - { - var source0 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static void Start() {} - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static Task M4() => null; - static Task M5() => null; - static void End() {} - - static async Task F() - { - Start(); - await M1(); - try - { - await M2(); - await M3(); - } - catch - { - await M4(); - await M5(); - } - End(); - } -}"); - var source1 = MarkedSource(@" -using System.Threading.Tasks; - -class C -{ - static void Start() {} - static Task M1() => null; - static Task M2() => null; - static Task M3() => null; - static Task M4() => null; - static Task M5() => null; - static void End() {} - - static async Task F() - { - Start(); - try - { - await M2(); - } - catch - { - await M4(); - } - End(); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - v0.VerifyIL("C.d__7.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 671 (0x29f) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__7 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Runtime.CompilerServices.TaskAwaiter V_4, - object V_5, - int V_6, - System.Runtime.CompilerServices.TaskAwaiter V_7, - System.Runtime.CompilerServices.TaskAwaiter V_8, - System.Exception V_9) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__7.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: switch ( - IL_0023, - IL_0025, - IL_0025, - IL_0027, - IL_002c) - IL_0021: br.s IL_0031 - IL_0023: br.s IL_0073 - IL_0025: br.s IL_009e - IL_0027: br IL_01da - IL_002c: br IL_0239 - - IL_0031: nop - IL_0032: call ""void C.Start()"" - IL_0037: nop - IL_0038: call ""System.Threading.Tasks.Task C.M1()"" - IL_003d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0042: stloc.1 - IL_0043: ldloca.s V_1 - IL_0045: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_004a: brtrue.s IL_008f - - IL_004c: ldarg.0 - IL_004d: ldc.i4.0 - IL_004e: dup - IL_004f: stloc.0 - IL_0050: stfld ""int C.d__7.<>1__state"" - IL_0055: ldarg.0 - IL_0056: ldloc.1 - IL_0057: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_005c: ldarg.0 - IL_005d: stloc.2 - IL_005e: ldarg.0 - IL_005f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_0064: ldloca.s V_1 - IL_0066: ldloca.s V_2 - IL_0068: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_006d: nop - IL_006e: leave IL_029e - - IL_0073: ldarg.0 - IL_0074: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0079: stloc.1 - IL_007a: ldarg.0 - IL_007b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0080: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0086: ldarg.0 - IL_0087: ldc.i4.m1 - IL_0088: dup - IL_0089: stloc.0 - IL_008a: stfld ""int C.d__7.<>1__state"" - - IL_008f: ldloca.s V_1 - IL_0091: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0096: nop - IL_0097: ldarg.0 - IL_0098: ldc.i4.0 - IL_0099: stfld ""int C.d__7.<>s__2"" - - IL_009e: nop - .try - { - IL_009f: ldloc.0 - IL_00a0: ldc.i4.1 - IL_00a1: beq.s IL_00ab - IL_00a3: br.s IL_00a5 - IL_00a5: ldloc.0 - IL_00a6: ldc.i4.2 - IL_00a7: beq.s IL_00ad - IL_00a9: br.s IL_00b2 - IL_00ab: br.s IL_00ee - IL_00ad: br IL_014f - - IL_00b2: nop - IL_00b3: call ""System.Threading.Tasks.Task C.M2()"" - IL_00b8: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_00bd: stloc.3 - IL_00be: ldloca.s V_3 - IL_00c0: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_00c5: brtrue.s IL_010a - - IL_00c7: ldarg.0 - IL_00c8: ldc.i4.1 - IL_00c9: dup - IL_00ca: stloc.0 - IL_00cb: stfld ""int C.d__7.<>1__state"" - IL_00d0: ldarg.0 - IL_00d1: ldloc.3 - IL_00d2: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_00d7: ldarg.0 - IL_00d8: stloc.2 - IL_00d9: ldarg.0 - IL_00da: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_00df: ldloca.s V_3 - IL_00e1: ldloca.s V_2 - IL_00e3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_00e8: nop - IL_00e9: leave IL_029e - - IL_00ee: ldarg.0 - IL_00ef: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_00f4: stloc.3 - IL_00f5: ldarg.0 - IL_00f6: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_00fb: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0101: ldarg.0 - IL_0102: ldc.i4.m1 - IL_0103: dup - IL_0104: stloc.0 - IL_0105: stfld ""int C.d__7.<>1__state"" - - IL_010a: ldloca.s V_3 - IL_010c: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0111: nop - IL_0112: call ""System.Threading.Tasks.Task C.M3()"" - IL_0117: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_011c: stloc.s V_4 - IL_011e: ldloca.s V_4 - IL_0120: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0125: brtrue.s IL_016c - - IL_0127: ldarg.0 - IL_0128: ldc.i4.2 - IL_0129: dup - IL_012a: stloc.0 - IL_012b: stfld ""int C.d__7.<>1__state"" - IL_0130: ldarg.0 - IL_0131: ldloc.s V_4 - IL_0133: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0138: ldarg.0 - IL_0139: stloc.2 - IL_013a: ldarg.0 - IL_013b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_0140: ldloca.s V_4 - IL_0142: ldloca.s V_2 - IL_0144: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_0149: nop - IL_014a: leave IL_029e - - IL_014f: ldarg.0 - IL_0150: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0155: stloc.s V_4 - IL_0157: ldarg.0 - IL_0158: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_015d: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0163: ldarg.0 - IL_0164: ldc.i4.m1 - IL_0165: dup - IL_0166: stloc.0 - IL_0167: stfld ""int C.d__7.<>1__state"" - - IL_016c: ldloca.s V_4 - IL_016e: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0173: nop - IL_0174: nop - IL_0175: leave.s IL_018a - } - catch object - { - IL_0177: stloc.s V_5 - IL_0179: ldarg.0 - IL_017a: ldloc.s V_5 - IL_017c: stfld ""object C.d__7.<>s__1"" - IL_0181: ldarg.0 - IL_0182: ldc.i4.1 - IL_0183: stfld ""int C.d__7.<>s__2"" - IL_0188: leave.s IL_018a - } - IL_018a: ldarg.0 - IL_018b: ldfld ""int C.d__7.<>s__2"" - IL_0190: stloc.s V_6 - IL_0192: ldloc.s V_6 - IL_0194: ldc.i4.1 - IL_0195: beq.s IL_019c - IL_0197: br IL_0261 - - IL_019c: nop - IL_019d: call ""System.Threading.Tasks.Task C.M4()"" - IL_01a2: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_01a7: stloc.s V_7 - IL_01a9: ldloca.s V_7 - IL_01ab: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_01b0: brtrue.s IL_01f7 - - IL_01b2: ldarg.0 - IL_01b3: ldc.i4.3 - IL_01b4: dup - IL_01b5: stloc.0 - IL_01b6: stfld ""int C.d__7.<>1__state"" - IL_01bb: ldarg.0 - IL_01bc: ldloc.s V_7 - IL_01be: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_01c3: ldarg.0 - IL_01c4: stloc.2 - IL_01c5: ldarg.0 - IL_01c6: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_01cb: ldloca.s V_7 - IL_01cd: ldloca.s V_2 - IL_01cf: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_01d4: nop - IL_01d5: leave IL_029e - - IL_01da: ldarg.0 - IL_01db: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_01e0: stloc.s V_7 - IL_01e2: ldarg.0 - IL_01e3: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_01e8: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_01ee: ldarg.0 - IL_01ef: ldc.i4.m1 - IL_01f0: dup - IL_01f1: stloc.0 - IL_01f2: stfld ""int C.d__7.<>1__state"" - - IL_01f7: ldloca.s V_7 - IL_01f9: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_01fe: nop - IL_01ff: call ""System.Threading.Tasks.Task C.M5()"" - IL_0204: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0209: stloc.s V_8 - IL_020b: ldloca.s V_8 - IL_020d: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0212: brtrue.s IL_0256 - - IL_0214: ldarg.0 - IL_0215: ldc.i4.4 - IL_0216: dup - IL_0217: stloc.0 - IL_0218: stfld ""int C.d__7.<>1__state"" - IL_021d: ldarg.0 - IL_021e: ldloc.s V_8 - IL_0220: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0225: ldarg.0 - IL_0226: stloc.2 - IL_0227: ldarg.0 - IL_0228: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_022d: ldloca.s V_8 - IL_022f: ldloca.s V_2 - IL_0231: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_0236: nop - IL_0237: leave.s IL_029e - - IL_0239: ldarg.0 - IL_023a: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_023f: stloc.s V_8 - IL_0241: ldarg.0 - IL_0242: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0247: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_024d: ldarg.0 - IL_024e: ldc.i4.m1 - IL_024f: dup - IL_0250: stloc.0 - IL_0251: stfld ""int C.d__7.<>1__state"" - - IL_0256: ldloca.s V_8 - IL_0258: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_025d: nop - IL_025e: nop - IL_025f: br.s IL_0261 - - IL_0261: ldarg.0 - IL_0262: ldnull - IL_0263: stfld ""object C.d__7.<>s__1"" - IL_0268: call ""void C.End()"" - IL_026d: nop - IL_026e: leave.s IL_028a - } - catch System.Exception - { - IL_0270: stloc.s V_9 - IL_0272: ldarg.0 - IL_0273: ldc.i4.s -2 - IL_0275: stfld ""int C.d__7.<>1__state"" - IL_027a: ldarg.0 - IL_027b: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_0280: ldloc.s V_9 - IL_0282: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0287: nop - IL_0288: leave.s IL_029e - } - IL_028a: ldarg.0 - IL_028b: ldc.i4.s -2 - IL_028d: stfld ""int C.d__7.<>1__state"" - IL_0292: ldarg.0 - IL_0293: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_0298: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_029d: nop - IL_029e: ret -} -"); - - diff1.VerifyIL("C.d__7.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 356 (0x164) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__7 V_2, - object V_3, - int V_4, - System.Runtime.CompilerServices.TaskAwaiter V_5, - System.Exception V_6) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__7.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.1 - IL_0009: beq.s IL_0013 - IL_000b: br.s IL_000d - IL_000d: ldloc.0 - IL_000e: ldc.i4.2 - IL_000f: beq.s IL_0015 - IL_0011: br.s IL_001a - IL_0013: br.s IL_0037 - IL_0015: br IL_00fe - IL_001a: ldloc.0 - IL_001b: ldc.i4.0 - IL_001c: blt.s IL_0029 - IL_001e: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedAsyncMethod + @""" - IL_0023: newobj ""System.InvalidOperationException..ctor(string)"" - IL_0028: throw - - IL_0029: nop - IL_002a: call ""void C.Start()"" - IL_002f: nop - IL_0030: ldarg.0 - IL_0031: ldc.i4.0 - IL_0032: stfld ""int C.d__7.<>s__4"" - - IL_0037: nop - .try - { - IL_0038: ldloc.0 - IL_0039: ldc.i4.1 - IL_003a: beq.s IL_003e - IL_003c: br.s IL_0040 - IL_003e: br.s IL_007c - - IL_0040: nop - IL_0041: call ""System.Threading.Tasks.Task C.M2()"" - IL_0046: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_004b: stloc.1 - IL_004c: ldloca.s V_1 - IL_004e: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0053: brtrue.s IL_0098 - - IL_0055: ldarg.0 - IL_0056: ldc.i4.1 - IL_0057: dup - IL_0058: stloc.0 - IL_0059: stfld ""int C.d__7.<>1__state"" - IL_005e: ldarg.0 - IL_005f: ldloc.1 - IL_0060: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0065: ldarg.0 - IL_0066: stloc.2 - IL_0067: ldarg.0 - IL_0068: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_006d: ldloca.s V_1 - IL_006f: ldloca.s V_2 - IL_0071: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_0076: nop - IL_0077: leave IL_0163 - - IL_007c: ldarg.0 - IL_007d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0082: stloc.1 - IL_0083: ldarg.0 - IL_0084: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0089: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_008f: ldarg.0 - IL_0090: ldc.i4.m1 - IL_0091: dup - IL_0092: stloc.0 - IL_0093: stfld ""int C.d__7.<>1__state"" - IL_0098: ldloca.s V_1 - IL_009a: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_009f: nop - IL_00a0: nop - IL_00a1: leave.s IL_00b4 - } - catch object - { - IL_00a3: stloc.3 - IL_00a4: ldarg.0 - IL_00a5: ldloc.3 - IL_00a6: stfld ""object C.d__7.<>s__3"" - IL_00ab: ldarg.0 - IL_00ac: ldc.i4.1 - IL_00ad: stfld ""int C.d__7.<>s__4"" - IL_00b2: leave.s IL_00b4 - } - IL_00b4: ldarg.0 - IL_00b5: ldfld ""int C.d__7.<>s__4"" - IL_00ba: stloc.s V_4 - IL_00bc: ldloc.s V_4 - IL_00be: ldc.i4.1 - IL_00bf: beq.s IL_00c3 - IL_00c1: br.s IL_0126 - - IL_00c3: nop - IL_00c4: call ""System.Threading.Tasks.Task C.M4()"" - IL_00c9: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_00ce: stloc.s V_5 - IL_00d0: ldloca.s V_5 - IL_00d2: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_00d7: brtrue.s IL_011b - - IL_00d9: ldarg.0 - IL_00da: ldc.i4.2 - IL_00db: dup - IL_00dc: stloc.0 - IL_00dd: stfld ""int C.d__7.<>1__state"" - IL_00e2: ldarg.0 - IL_00e3: ldloc.s V_5 - IL_00e5: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_00ea: ldarg.0 - IL_00eb: stloc.2 - IL_00ec: ldarg.0 - IL_00ed: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_00f2: ldloca.s V_5 - IL_00f4: ldloca.s V_2 - IL_00f6: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__7>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__7)"" - IL_00fb: nop - IL_00fc: leave.s IL_0163 - - IL_00fe: ldarg.0 - IL_00ff: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_0104: stloc.s V_5 - IL_0106: ldarg.0 - IL_0107: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__7.<>u__1"" - IL_010c: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0112: ldarg.0 - IL_0113: ldc.i4.m1 - IL_0114: dup - IL_0115: stloc.0 - IL_0116: stfld ""int C.d__7.<>1__state"" - - IL_011b: ldloca.s V_5 - IL_011d: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0122: nop - IL_0123: nop - IL_0124: br.s IL_0126 - - IL_0126: ldarg.0 - IL_0127: ldnull - IL_0128: stfld ""object C.d__7.<>s__3"" - IL_012d: call ""void C.End()"" - IL_0132: nop - IL_0133: leave.s IL_014f - } - catch System.Exception - { - IL_0135: stloc.s V_6 - IL_0137: ldarg.0 - IL_0138: ldc.i4.s -2 - IL_013a: stfld ""int C.d__7.<>1__state"" - IL_013f: ldarg.0 - IL_0140: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_0145: ldloc.s V_6 - IL_0147: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_014c: nop - IL_014d: leave.s IL_0163 - } - IL_014f: ldarg.0 - IL_0150: ldc.i4.s -2 - IL_0152: stfld ""int C.d__7.<>1__state"" - IL_0157: ldarg.0 - IL_0158: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__7.<>t__builder"" - IL_015d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_0162: nop - IL_0163: ret -} -"); - } - - [Fact] - public void UpdateAsync_AwaitDeclarationMappedToNonAwait() - { - var source0 = MarkedSource(@" -using System; -using System.Threading.Tasks; - -class C -{ - static async Task F() - { - await Task.CompletedTask; - IAsyncDisposable x = G(), y = G(); - } - - static IAsyncDisposable G() => null; -}"); - var source1 = MarkedSource(@" -using System; -using System.Threading.Tasks; - -class C -{ - static async Task F() - { - await Task.CompletedTask; - await using IAsyncDisposable x = G(), y = G(); - } - - static IAsyncDisposable G() => null; -}"); - var asyncStreamsTree = Parse(AsyncStreamsTypes); - - var compilation0 = CreateCompilationWithTasksExtensions(new[] { source0.Tree, asyncStreamsTree }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(new[] { source1.Tree, asyncStreamsTree }); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - // Note that the CDI contains local variable declaration mapping to facilitate local variable slot allocation, - // but these are not included in the state machine map since the V0 version of the local declaration statement does not have "await" keyword. - // Therefore, the V1 version will not be able ot match the local declaration statements to their previous versions when emitting - // state machine states and create new states for them as expected. - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - - - -"); - - // note preserved hoisted variables x, y: - - v0.VerifySynthesizedFields("C.d__0", - "int <>1__state", - "System.Runtime.CompilerServices.AsyncTaskMethodBuilder <>t__builder", - "System.IAsyncDisposable 5__1", - "System.IAsyncDisposable 5__2", - "System.Runtime.CompilerServices.TaskAwaiter <>u__1"); - - diff1.VerifySynthesizedFields("C.d__0", - "<>1__state: int", - "<>t__builder: System.Runtime.CompilerServices.AsyncTaskMethodBuilder", - "5__1: System.IAsyncDisposable", - "5__2: System.IAsyncDisposable", - "<>s__3: object", - "<>s__4: int", - "<>s__5: object", - "<>s__6: int", - "<>u__1: System.Runtime.CompilerServices.TaskAwaiter", - "<>u__2: System.Runtime.CompilerServices.ValueTaskAwaiter"); - - diff1.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 678 (0x2a6) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - object V_3, - System.Runtime.CompilerServices.ValueTaskAwaiter V_4, - System.Threading.Tasks.ValueTask V_5, - System.Exception V_6, - int V_7, - System.Runtime.CompilerServices.ValueTaskAwaiter V_8) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_0024 - IL_001b: br.s IL_0060 - IL_001d: br.s IL_009d - IL_001f: br IL_01e9 - IL_0024: nop - IL_0025: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get"" - IL_002a: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_002f: stloc.1 - IL_0030: ldloca.s V_1 - IL_0032: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0037: brtrue.s IL_007c - IL_0039: ldarg.0 - IL_003a: ldc.i4.0 - IL_003b: dup - IL_003c: stloc.0 - IL_003d: stfld ""int C.d__0.<>1__state"" - IL_0042: ldarg.0 - IL_0043: ldloc.1 - IL_0044: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_0049: ldarg.0 - IL_004a: stloc.2 - IL_004b: ldarg.0 - IL_004c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder"" - IL_0051: ldloca.s V_1 - IL_0053: ldloca.s V_2 - IL_0055: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_005a: nop - IL_005b: leave IL_02a5 - IL_0060: ldarg.0 - IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_0066: stloc.1 - IL_0067: ldarg.0 - IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0073: ldarg.0 - IL_0074: ldc.i4.m1 - IL_0075: dup - IL_0076: stloc.0 - IL_0077: stfld ""int C.d__0.<>1__state"" - IL_007c: ldloca.s V_1 - IL_007e: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0083: nop - IL_0084: ldarg.0 - IL_0085: call ""System.IAsyncDisposable C.G()"" - IL_008a: stfld ""System.IAsyncDisposable C.d__0.5__1"" - IL_008f: ldarg.0 - IL_0090: ldnull - IL_0091: stfld ""object C.d__0.<>s__3"" - IL_0096: ldarg.0 - IL_0097: ldc.i4.0 - IL_0098: stfld ""int C.d__0.<>s__4"" - IL_009d: nop - .try - { - IL_009e: ldloc.0 - IL_009f: ldc.i4.1 - IL_00a0: beq.s IL_00a4 - IL_00a2: br.s IL_00a6 - IL_00a4: br.s IL_0123 - IL_00a6: ldarg.0 - IL_00a7: call ""System.IAsyncDisposable C.G()"" - IL_00ac: stfld ""System.IAsyncDisposable C.d__0.5__2"" - IL_00b1: ldarg.0 - IL_00b2: ldnull - IL_00b3: stfld ""object C.d__0.<>s__5"" - IL_00b8: ldarg.0 - IL_00b9: ldc.i4.0 - IL_00ba: stfld ""int C.d__0.<>s__6"" - .try - { - IL_00bf: br.s IL_00c1 - IL_00c1: ldarg.0 - IL_00c2: ldc.i4.1 - IL_00c3: stfld ""int C.d__0.<>s__6"" - IL_00c8: leave.s IL_00d4 - } - catch object - { - IL_00ca: stloc.3 - IL_00cb: ldarg.0 - IL_00cc: ldloc.3 - IL_00cd: stfld ""object C.d__0.<>s__5"" - IL_00d2: leave.s IL_00d4 - } - IL_00d4: ldarg.0 - IL_00d5: ldfld ""System.IAsyncDisposable C.d__0.5__2"" - IL_00da: brfalse.s IL_0148 - IL_00dc: ldarg.0 - IL_00dd: ldfld ""System.IAsyncDisposable C.d__0.5__2"" - IL_00e2: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" - IL_00e7: stloc.s V_5 - IL_00e9: ldloca.s V_5 - IL_00eb: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" - IL_00f0: stloc.s V_4 - IL_00f2: ldloca.s V_4 - IL_00f4: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" - IL_00f9: brtrue.s IL_0140 - IL_00fb: ldarg.0 - IL_00fc: ldc.i4.1 - IL_00fd: dup - IL_00fe: stloc.0 - IL_00ff: stfld ""int C.d__0.<>1__state"" - IL_0104: ldarg.0 - IL_0105: ldloc.s V_4 - IL_0107: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__0.<>u__2"" - IL_010c: ldarg.0 - IL_010d: stloc.2 - IL_010e: ldarg.0 - IL_010f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder"" - IL_0114: ldloca.s V_4 - IL_0116: ldloca.s V_2 - IL_0118: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__0)"" - IL_011d: nop - IL_011e: leave IL_02a5 - IL_0123: ldarg.0 - IL_0124: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__0.<>u__2"" - IL_0129: stloc.s V_4 - IL_012b: ldarg.0 - IL_012c: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__0.<>u__2"" - IL_0131: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" - IL_0137: ldarg.0 - IL_0138: ldc.i4.m1 - IL_0139: dup - IL_013a: stloc.0 - IL_013b: stfld ""int C.d__0.<>1__state"" - IL_0140: ldloca.s V_4 - IL_0142: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" - IL_0147: nop - IL_0148: ldarg.0 - IL_0149: ldfld ""object C.d__0.<>s__5"" - IL_014e: stloc.3 - IL_014f: ldloc.3 - IL_0150: brfalse.s IL_016d - IL_0152: ldloc.3 - IL_0153: isinst ""System.Exception"" - IL_0158: stloc.s V_6 - IL_015a: ldloc.s V_6 - IL_015c: brtrue.s IL_0160 - IL_015e: ldloc.3 - IL_015f: throw - IL_0160: ldloc.s V_6 - IL_0162: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" - IL_0167: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" - IL_016c: nop - IL_016d: ldarg.0 - IL_016e: ldfld ""int C.d__0.<>s__6"" - IL_0173: stloc.s V_7 - IL_0175: ldloc.s V_7 - IL_0177: ldc.i4.1 - IL_0178: beq.s IL_017c - IL_017a: br.s IL_017e - IL_017c: br.s IL_0187 - IL_017e: ldarg.0 - IL_017f: ldnull - IL_0180: stfld ""object C.d__0.<>s__5"" - IL_0185: leave.s IL_019a - IL_0187: ldarg.0 - IL_0188: ldc.i4.1 - IL_0189: stfld ""int C.d__0.<>s__4"" - IL_018e: leave.s IL_019a - } - catch object - { - IL_0190: stloc.3 - IL_0191: ldarg.0 - IL_0192: ldloc.3 - IL_0193: stfld ""object C.d__0.<>s__3"" - IL_0198: leave.s IL_019a - } - IL_019a: ldarg.0 - IL_019b: ldfld ""System.IAsyncDisposable C.d__0.5__1"" - IL_01a0: brfalse.s IL_020e - IL_01a2: ldarg.0 - IL_01a3: ldfld ""System.IAsyncDisposable C.d__0.5__1"" - IL_01a8: callvirt ""System.Threading.Tasks.ValueTask System.IAsyncDisposable.DisposeAsync()"" - IL_01ad: stloc.s V_5 - IL_01af: ldloca.s V_5 - IL_01b1: call ""System.Runtime.CompilerServices.ValueTaskAwaiter System.Threading.Tasks.ValueTask.GetAwaiter()"" - IL_01b6: stloc.s V_8 - IL_01b8: ldloca.s V_8 - IL_01ba: call ""bool System.Runtime.CompilerServices.ValueTaskAwaiter.IsCompleted.get"" - IL_01bf: brtrue.s IL_0206 - IL_01c1: ldarg.0 - IL_01c2: ldc.i4.2 - IL_01c3: dup - IL_01c4: stloc.0 - IL_01c5: stfld ""int C.d__0.<>1__state"" - IL_01ca: ldarg.0 - IL_01cb: ldloc.s V_8 - IL_01cd: stfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__0.<>u__2"" - IL_01d2: ldarg.0 - IL_01d3: stloc.2 - IL_01d4: ldarg.0 - IL_01d5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder"" - IL_01da: ldloca.s V_8 - IL_01dc: ldloca.s V_2 - IL_01de: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__0>(ref System.Runtime.CompilerServices.ValueTaskAwaiter, ref C.d__0)"" - IL_01e3: nop - IL_01e4: leave IL_02a5 - IL_01e9: ldarg.0 - IL_01ea: ldfld ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__0.<>u__2"" - IL_01ef: stloc.s V_8 - IL_01f1: ldarg.0 - IL_01f2: ldflda ""System.Runtime.CompilerServices.ValueTaskAwaiter C.d__0.<>u__2"" - IL_01f7: initobj ""System.Runtime.CompilerServices.ValueTaskAwaiter"" - IL_01fd: ldarg.0 - IL_01fe: ldc.i4.m1 - IL_01ff: dup - IL_0200: stloc.0 - IL_0201: stfld ""int C.d__0.<>1__state"" - IL_0206: ldloca.s V_8 - IL_0208: call ""void System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()"" - IL_020d: nop - IL_020e: ldarg.0 - IL_020f: ldfld ""object C.d__0.<>s__3"" - IL_0214: stloc.3 - IL_0215: ldloc.3 - IL_0216: brfalse.s IL_0233 - IL_0218: ldloc.3 - IL_0219: isinst ""System.Exception"" - IL_021e: stloc.s V_6 - IL_0220: ldloc.s V_6 - IL_0222: brtrue.s IL_0226 - IL_0224: ldloc.3 - IL_0225: throw - IL_0226: ldloc.s V_6 - IL_0228: call ""System.Runtime.ExceptionServices.ExceptionDispatchInfo System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(System.Exception)"" - IL_022d: callvirt ""void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()"" - IL_0232: nop - IL_0233: ldarg.0 - IL_0234: ldfld ""int C.d__0.<>s__4"" - IL_0239: stloc.s V_7 - IL_023b: ldloc.s V_7 - IL_023d: ldc.i4.1 - IL_023e: beq.s IL_0242 - IL_0240: br.s IL_0244 - IL_0242: leave.s IL_0283 - IL_0244: ldarg.0 - IL_0245: ldnull - IL_0246: stfld ""object C.d__0.<>s__3"" - IL_024b: ldarg.0 - IL_024c: ldnull - IL_024d: stfld ""System.IAsyncDisposable C.d__0.5__1"" - IL_0252: ldarg.0 - IL_0253: ldnull - IL_0254: stfld ""System.IAsyncDisposable C.d__0.5__2"" - IL_0259: leave.s IL_0283 - } - catch System.Exception - { - IL_025b: stloc.s V_6 - IL_025d: ldarg.0 - IL_025e: ldc.i4.s -2 - IL_0260: stfld ""int C.d__0.<>1__state"" - IL_0265: ldarg.0 - IL_0266: ldnull - IL_0267: stfld ""System.IAsyncDisposable C.d__0.5__1"" - IL_026c: ldarg.0 - IL_026d: ldnull - IL_026e: stfld ""System.IAsyncDisposable C.d__0.5__2"" - IL_0273: ldarg.0 - IL_0274: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder"" - IL_0279: ldloc.s V_6 - IL_027b: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_0280: nop - IL_0281: leave.s IL_02a5 - } - IL_0283: ldarg.0 - IL_0284: ldc.i4.s -2 - IL_0286: stfld ""int C.d__0.<>1__state"" - IL_028b: ldarg.0 - IL_028c: ldnull - IL_028d: stfld ""System.IAsyncDisposable C.d__0.5__1"" - IL_0292: ldarg.0 - IL_0293: ldnull - IL_0294: stfld ""System.IAsyncDisposable C.d__0.5__2"" - IL_0299: ldarg.0 - IL_029a: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__0.<>t__builder"" - IL_029f: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()"" - IL_02a4: nop - IL_02a5: ret -}"); - } - - [Fact] - public void UpdateIterator_UserDefinedVariables_NoChange() - { - var source0 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static IEnumerable F(int p) - { - int x = p; - yield return 1; - } -}"); - var source1 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static IEnumerable F(int p) - { - int x = p; - yield return 2; - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - var symReader = v0.CreateSymReader(); - - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - // Verify delta metadata contains expected rows. - using var md1 = diff1.GetMetadata(); - - // Verify that no new TypeDefs, FieldDefs or MethodDefs were added, - // 3 methods were updated: - // - the kick-off method (might be changed if the method previously wasn't an iterator) - // - Finally method - // - MoveNext method - CheckEncLogDefinitions(md1.Reader, - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.Param, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 69 (0x45) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0016 - IL_0012: br.s IL_0018 - IL_0014: br.s IL_003c - IL_0016: ldc.i4.0 - IL_0017: ret - IL_0018: ldarg.0 - IL_0019: ldc.i4.m1 - IL_001a: stfld ""int C.d__0.<>1__state"" - IL_001f: nop - IL_0020: ldarg.0 - IL_0021: ldarg.0 - IL_0022: ldfld ""int C.d__0.p"" - IL_0027: stfld ""int C.d__0.5__1"" - IL_002c: ldarg.0 - IL_002d: ldc.i4.2 - IL_002e: stfld ""int C.d__0.<>2__current"" - IL_0033: ldarg.0 - IL_0034: ldc.i4.1 - IL_0035: stfld ""int C.d__0.<>1__state"" - IL_003a: ldc.i4.1 - IL_003b: ret - IL_003c: ldarg.0 - IL_003d: ldc.i4.m1 - IL_003e: stfld ""int C.d__0.<>1__state"" - IL_0043: ldc.i4.0 - IL_0044: ret -}"); - } - - [Fact] - public void UpdateIterator_UserDefinedVariables_AddVariable() - { - var source0 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F(int p) - { - int x = p; - yield return x; - } -}"); - var source1 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F(int p) - { - int y = 1234; - int x = p; - yield return y; - Console.WriteLine(x); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - var symReader = v0.CreateSymReader(); - - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - // Verify delta metadata contains expected rows. - using var md1 = diff1.GetMetadata(); - - // 1 field def added & 3 methods updated - CheckEncLogDefinitions(md1.Reader, - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(7, TableIndex.Field, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.Param, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 97 (0x61) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0016 - IL_0012: br.s IL_0018 - IL_0014: br.s IL_004c - IL_0016: ldc.i4.0 - IL_0017: ret - IL_0018: ldarg.0 - IL_0019: ldc.i4.m1 - IL_001a: stfld ""int C.d__0.<>1__state"" - IL_001f: nop - IL_0020: ldarg.0 - IL_0021: ldc.i4 0x4d2 - IL_0026: stfld ""int C.d__0.5__2"" - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld ""int C.d__0.p"" - IL_0032: stfld ""int C.d__0.5__1"" - IL_0037: ldarg.0 - IL_0038: ldarg.0 - IL_0039: ldfld ""int C.d__0.5__2"" - IL_003e: stfld ""int C.d__0.<>2__current"" - IL_0043: ldarg.0 - IL_0044: ldc.i4.1 - IL_0045: stfld ""int C.d__0.<>1__state"" - IL_004a: ldc.i4.1 - IL_004b: ret - IL_004c: ldarg.0 - IL_004d: ldc.i4.m1 - IL_004e: stfld ""int C.d__0.<>1__state"" - IL_0053: ldarg.0 - IL_0054: ldfld ""int C.d__0.5__1"" - IL_0059: call ""void System.Console.WriteLine(int)"" - IL_005e: nop - IL_005f: ldc.i4.0 - IL_0060: ret -}"); - } - - [Fact] - public void UpdateIterator_UserDefinedVariables_AddAndRemoveVariable() - { - var source0 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F(int p) - { - int x = p; - yield return x; - } -}"); - var source1 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F(int p) - { - int y = 1234; - yield return y; - Console.WriteLine(p); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - var symReader = v0.CreateSymReader(); - - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - // Verify delta metadata contains expected rows. - using var md1 = diff1.GetMetadata(); - - // 1 field def added & 3 methods updated - CheckEncLogDefinitions(md1.Reader, - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(7, TableIndex.Field, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.Param, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 85 (0x55) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0016 - IL_0012: br.s IL_0018 - IL_0014: br.s IL_0040 - IL_0016: ldc.i4.0 - IL_0017: ret - IL_0018: ldarg.0 - IL_0019: ldc.i4.m1 - IL_001a: stfld ""int C.d__0.<>1__state"" - IL_001f: nop - IL_0020: ldarg.0 - IL_0021: ldc.i4 0x4d2 - IL_0026: stfld ""int C.d__0.5__2"" - IL_002b: ldarg.0 - IL_002c: ldarg.0 - IL_002d: ldfld ""int C.d__0.5__2"" - IL_0032: stfld ""int C.d__0.<>2__current"" - IL_0037: ldarg.0 - IL_0038: ldc.i4.1 - IL_0039: stfld ""int C.d__0.<>1__state"" - IL_003e: ldc.i4.1 - IL_003f: ret - IL_0040: ldarg.0 - IL_0041: ldc.i4.m1 - IL_0042: stfld ""int C.d__0.<>1__state"" - IL_0047: ldarg.0 - IL_0048: ldfld ""int C.d__0.p"" - IL_004d: call ""void System.Console.WriteLine(int)"" - IL_0052: nop - IL_0053: ldc.i4.0 - IL_0054: ret -}"); - } - - [Fact] - public void UpdateIterator_UserDefinedVariables_ChangeVariableType() - { - var source0 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F() - { - var x = 1; - yield return 1; - Console.WriteLine(x); - } -}"); - var source1 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F() - { - var x = 1.0; - yield return 2; - Console.WriteLine(x); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - var symReader = v0.CreateSymReader(); - - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - // Verify delta metadata contains expected rows. - using var md1 = diff1.GetMetadata(); - - // 1 field def added & 3 methods updated - CheckEncLogDefinitions(md1.Reader, - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(5, TableIndex.Field, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 84 (0x54) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0016 - IL_0012: br.s IL_0018 - IL_0014: br.s IL_003f - IL_0016: ldc.i4.0 - IL_0017: ret - IL_0018: ldarg.0 - IL_0019: ldc.i4.m1 - IL_001a: stfld ""int C.d__0.<>1__state"" - IL_001f: nop - IL_0020: ldarg.0 - IL_0021: ldc.r8 1 - IL_002a: stfld ""double C.d__0.5__2"" - IL_002f: ldarg.0 - IL_0030: ldc.i4.2 - IL_0031: stfld ""int C.d__0.<>2__current"" - IL_0036: ldarg.0 - IL_0037: ldc.i4.1 - IL_0038: stfld ""int C.d__0.<>1__state"" - IL_003d: ldc.i4.1 - IL_003e: ret - IL_003f: ldarg.0 - IL_0040: ldc.i4.m1 - IL_0041: stfld ""int C.d__0.<>1__state"" - IL_0046: ldarg.0 - IL_0047: ldfld ""double C.d__0.5__2"" - IL_004c: call ""void System.Console.WriteLine(double)"" - IL_0051: nop - IL_0052: ldc.i4.0 - IL_0053: ret -}"); - } - - [Fact] - public void UpdateIterator_SynthesizedVariables_ChangeVariableType() - { - var source0 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F() - { - foreach (object item in new[] { 1 }) { yield return 1; } - } -}"); - var source1 = MarkedSource(@" -using System; -using System.Collections.Generic; - -class C -{ - static IEnumerable F() - { - foreach (object item in new[] { 1.0 }) { yield return 1; } - } -}"); - // Rude edit but the compiler should handle it. - - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0, symbolValidator: module => - { - Assert.Equal(new[] - { - "<>1__state: int", - "<>2__current: int", - "<>l__initialThreadId: int", - "<>s__1: int[]", - "<>s__2: int", - "5__3: object" - }, module.GetFieldNamesAndTypes("C.d__0")); - }); - - var symReader = v0.CreateSymReader(); - - using var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var method0 = compilation0.GetMember("C.F"); - var method1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - // Verify delta metadata contains expected rows. - using var md1 = diff1.GetMetadata(); - - // 1 field def added & 3 methods updated - CheckEncLogDefinitions(md1.Reader, - Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), - Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), - Row(7, TableIndex.Field, EditAndContinueOperation.Default), - Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), - Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), - Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 161 (0xa1) - .maxstack 5 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.0 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0016 - IL_0012: br.s IL_0018 - IL_0014: br.s IL_006b - IL_0016: ldc.i4.0 - IL_0017: ret - IL_0018: ldarg.0 - IL_0019: ldc.i4.m1 - IL_001a: stfld ""int C.d__0.<>1__state"" - IL_001f: nop - IL_0020: nop - IL_0021: ldarg.0 - IL_0022: ldc.i4.1 - IL_0023: newarr ""double"" - IL_0028: dup - IL_0029: ldc.i4.0 - IL_002a: ldc.r8 1 - IL_0033: stelem.r8 - IL_0034: stfld ""double[] C.d__0.<>s__4"" - IL_0039: ldarg.0 - IL_003a: ldc.i4.0 - IL_003b: stfld ""int C.d__0.<>s__2"" - IL_0040: br.s IL_0088 - IL_0042: ldarg.0 - IL_0043: ldarg.0 - IL_0044: ldfld ""double[] C.d__0.<>s__4"" - IL_0049: ldarg.0 - IL_004a: ldfld ""int C.d__0.<>s__2"" - IL_004f: ldelem.r8 - IL_0050: box ""double"" - IL_0055: stfld ""object C.d__0.5__3"" - IL_005a: nop - IL_005b: ldarg.0 - IL_005c: ldc.i4.1 - IL_005d: stfld ""int C.d__0.<>2__current"" - IL_0062: ldarg.0 - IL_0063: ldc.i4.1 - IL_0064: stfld ""int C.d__0.<>1__state"" - IL_0069: ldc.i4.1 - IL_006a: ret - IL_006b: ldarg.0 - IL_006c: ldc.i4.m1 - IL_006d: stfld ""int C.d__0.<>1__state"" - IL_0072: nop - IL_0073: ldarg.0 - IL_0074: ldnull - IL_0075: stfld ""object C.d__0.5__3"" - IL_007a: ldarg.0 - IL_007b: ldarg.0 - IL_007c: ldfld ""int C.d__0.<>s__2"" - IL_0081: ldc.i4.1 - IL_0082: add - IL_0083: stfld ""int C.d__0.<>s__2"" - IL_0088: ldarg.0 - IL_0089: ldfld ""int C.d__0.<>s__2"" - IL_008e: ldarg.0 - IL_008f: ldfld ""double[] C.d__0.<>s__4"" - IL_0094: ldlen - IL_0095: conv.i4 - IL_0096: blt.s IL_0042 - IL_0098: ldarg.0 - IL_0099: ldnull - IL_009a: stfld ""double[] C.d__0.<>s__4"" - IL_009f: ldc.i4.0 - IL_00a0: ret -}"); - } - - [Fact] - public void UpdateIterator_YieldReturn_Add() - { - var source0 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static int M1() => 1; - static int M2() => 2; - static int M3() => 3; - static int M4() => 4; - static void End() {} - - static IEnumerable F() - { - yield return M1(); - yield return M2(); - End(); - } -}"); - var source1 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static int M1() => 1; - static int M2() => 2; - static int M3() => 3; - static int M4() => 4; - static void End() {} - - static IEnumerable F() - { - yield return M1(); - yield return M3(); - yield return M4(); - yield return M2(); - End(); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - -"); - v0.VerifyPdb("C+d__5.MoveNext", @" - - - - - - - - - - - - - - - -", options: PdbValidationOptions.ExcludeSequencePoints); - - v0.VerifyIL("C.d__5.System.Collections.IEnumerator.MoveNext", @" - { - // Code size 105 (0x69) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__5.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_0021 - IL_001b: br.s IL_0023 - IL_001d: br.s IL_003f - IL_001f: br.s IL_005a - - IL_0021: ldc.i4.0 - IL_0022: ret - - IL_0023: ldarg.0 - IL_0024: ldc.i4.m1 - IL_0025: stfld ""int C.d__5.<>1__state"" - IL_002a: nop - IL_002b: ldarg.0 - IL_002c: call ""int C.M1()"" - IL_0031: stfld ""int C.d__5.<>2__current"" - IL_0036: ldarg.0 - IL_0037: ldc.i4.1 - IL_0038: stfld ""int C.d__5.<>1__state"" - IL_003d: ldc.i4.1 - IL_003e: ret - - IL_003f: ldarg.0 - IL_0040: ldc.i4.m1 - IL_0041: stfld ""int C.d__5.<>1__state"" - IL_0046: ldarg.0 - IL_0047: call ""int C.M2()"" - IL_004c: stfld ""int C.d__5.<>2__current"" - IL_0051: ldarg.0 - IL_0052: ldc.i4.2 - IL_0053: stfld ""int C.d__5.<>1__state"" - IL_0058: ldc.i4.1 - IL_0059: ret - - IL_005a: ldarg.0 - IL_005b: ldc.i4.m1 - IL_005c: stfld ""int C.d__5.<>1__state"" - IL_0061: call ""void C.End()"" - IL_0066: nop - IL_0067: ldc.i4.0 - IL_0068: ret -}"); - - diff1.VerifyIL("C.d__5.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 171 (0xab) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__5.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: switch ( - IL_0023, - IL_0025, - IL_0027, - IL_0029, - IL_002b) - IL_0021: br.s IL_002d - IL_0023: br.s IL_002f - IL_0025: br.s IL_004b - IL_0027: br.s IL_009c - IL_0029: br.s IL_0066 - IL_002b: br.s IL_0081 - - IL_002d: ldc.i4.0 - IL_002e: ret - - IL_002f: ldarg.0 - IL_0030: ldc.i4.m1 - IL_0031: stfld ""int C.d__5.<>1__state"" - IL_0036: nop - IL_0037: ldarg.0 - IL_0038: call ""int C.M1()"" - IL_003d: stfld ""int C.d__5.<>2__current"" - IL_0042: ldarg.0 - IL_0043: ldc.i4.1 - IL_0044: stfld ""int C.d__5.<>1__state"" - IL_0049: ldc.i4.1 - IL_004a: ret - - IL_004b: ldarg.0 - IL_004c: ldc.i4.m1 - IL_004d: stfld ""int C.d__5.<>1__state"" - IL_0052: ldarg.0 - IL_0053: call ""int C.M3()"" - IL_0058: stfld ""int C.d__5.<>2__current"" - IL_005d: ldarg.0 - IL_005e: ldc.i4.3 - IL_005f: stfld ""int C.d__5.<>1__state"" - IL_0064: ldc.i4.1 - IL_0065: ret - - IL_0066: ldarg.0 - IL_0067: ldc.i4.m1 - IL_0068: stfld ""int C.d__5.<>1__state"" - IL_006d: ldarg.0 - IL_006e: call ""int C.M4()"" - IL_0073: stfld ""int C.d__5.<>2__current"" - IL_0078: ldarg.0 - IL_0079: ldc.i4.4 - IL_007a: stfld ""int C.d__5.<>1__state"" - IL_007f: ldc.i4.1 - IL_0080: ret - - IL_0081: ldarg.0 - IL_0082: ldc.i4.m1 - IL_0083: stfld ""int C.d__5.<>1__state"" - IL_0088: ldarg.0 - IL_0089: call ""int C.M2()"" - IL_008e: stfld ""int C.d__5.<>2__current"" - IL_0093: ldarg.0 - IL_0094: ldc.i4.2 - IL_0095: stfld ""int C.d__5.<>1__state"" - IL_009a: ldc.i4.1 - IL_009b: ret - - IL_009c: ldarg.0 - IL_009d: ldc.i4.m1 - IL_009e: stfld ""int C.d__5.<>1__state"" - IL_00a3: call ""void C.End()"" - IL_00a8: nop - IL_00a9: ldc.i4.0 - IL_00aa: ret -} -"); - } - - [Fact] - public void UpdateIterator_YieldReturn_Remove() - { - var source0 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static int M1() => 1; - static int M2() => 2; - static int M3() => 3; - static int M4() => 4; - static void End() {} - - static IEnumerable F() - { - yield return M1(); - yield return M2(); - yield return M3(); - yield return M4(); - End(); - } -}"); - var source1 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static int M1() => 1; - static int M2() => 2; - static int M3() => 3; - static int M4() => 4; - static void End() {} - - static IEnumerable F() - { - yield return M2(); - yield return M3(); - End(); - } -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - diff1.VerifyIL("C.d__5.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 124 (0x7c) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__5.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: switch ( - IL_001f, - IL_0025, - IL_0021, - IL_0023) - IL_001d: br.s IL_0025 - IL_001f: br.s IL_0036 - IL_0021: br.s IL_0052 - IL_0023: br.s IL_006d - IL_0025: ldloc.0 - IL_0026: ldc.i4.1 - IL_0027: blt.s IL_0034 - IL_0029: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedIteratorMethod + @""" - IL_002e: newobj ""System.InvalidOperationException..ctor(string)"" - IL_0033: throw - - IL_0034: ldc.i4.0 - IL_0035: ret - - IL_0036: ldarg.0 - IL_0037: ldc.i4.m1 - IL_0038: stfld ""int C.d__5.<>1__state"" - IL_003d: nop - IL_003e: ldarg.0 - IL_003f: call ""int C.M2()"" - IL_0044: stfld ""int C.d__5.<>2__current"" - IL_0049: ldarg.0 - IL_004a: ldc.i4.2 - IL_004b: stfld ""int C.d__5.<>1__state"" - IL_0050: ldc.i4.1 - IL_0051: ret - - IL_0052: ldarg.0 - IL_0053: ldc.i4.m1 - IL_0054: stfld ""int C.d__5.<>1__state"" - IL_0059: ldarg.0 - IL_005a: call ""int C.M3()"" - IL_005f: stfld ""int C.d__5.<>2__current"" - IL_0064: ldarg.0 - IL_0065: ldc.i4.3 - IL_0066: stfld ""int C.d__5.<>1__state"" - IL_006b: ldc.i4.1 - IL_006c: ret - - IL_006d: ldarg.0 - IL_006e: ldc.i4.m1 - IL_006f: stfld ""int C.d__5.<>1__state"" - IL_0074: call ""void C.End()"" - IL_0079: nop - IL_007a: ldc.i4.0 - IL_007b: ret -} -"); - } - - [Fact] - public void UpdateIterator_YieldReturn_Add_Finally_Try() - { - var source0 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static IEnumerable F() - { - yield return M1(); - - try - { - yield return M2(); - } - finally - { - Finally1(0); - } - - yield return M3(); - - End(); - } - - static int M1() => 1; - static int M2() => 2; - static int M3() => 3; - static int M4() => 4; - static void End() {} - static void Finally1(int gen) {} - static void Finally2(int gen) {} - static void Finally3(int gen) {} -}"); - var source1 = MarkedSource(@" -using System.Collections.Generic; - -class C -{ - static IEnumerable F() - { - try - { - yield return M1(); - } - finally - { - Finally2(1); - } - - try - { - yield return M2(); - try - { - yield return M4(); - } - finally - { - Finally3(1); - } - } - finally - { - Finally1(1); - } - - yield return M3(); - - End(); - } - - static int M1() => 1; - static int M2() => 2; - static int M3() => 3; - static int M4() => 4; - static void End() {} - static void Finally1(int gen) {} - static void Finally2(int gen) {} - static void Finally3(int gen) {} -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); - - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - - -"); - - diff1.VerifySynthesizedMembers( - "C: {d__0}", - "C.d__0: {" + string.Join(", ", new[] - { - "<>1__state", - "<>2__current", - "<>l__initialThreadId", - "System.IDisposable.Dispose", - "MoveNext", - "<>m__Finally2", - "<>m__Finally1", - "<>m__Finally3", - "System.Collections.Generic.IEnumerator.get_Current", - "System.Collections.IEnumerator.Reset, System.Collections.IEnumerator.get_Current", - "System.Collections.Generic.IEnumerable.GetEnumerator", - "System.Collections.IEnumerable.GetEnumerator", - "System.Collections.Generic.IEnumerator.Current", - "System.Collections.IEnumerator.Current" - }) + "}"); - - diff1.VerifyIL("C.d__0.<>m__Finally1", @" -{ - // Code size 17 (0x11) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.m1 - IL_0002: stfld ""int C.d__0.<>1__state"" - IL_0007: nop - IL_0008: ldc.i4.1 - IL_0009: call ""void C.Finally1(int)"" - IL_000e: nop - IL_000f: nop - IL_0010: ret -} -"); - diff1.VerifyIL("C.d__0.<>m__Finally2", @" -{ - // Code size 17 (0x11) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.m1 - IL_0002: stfld ""int C.d__0.<>1__state"" - IL_0007: nop - IL_0008: ldc.i4.1 - IL_0009: call ""void C.Finally2(int)"" - IL_000e: nop - IL_000f: nop - IL_0010: ret -} -"); - diff1.VerifyIL("C.d__0.<>m__Finally3", @" -{ - // Code size 18 (0x12) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.s -3 - IL_0003: stfld ""int C.d__0.<>1__state"" - IL_0008: nop - IL_0009: ldc.i4.1 - IL_000a: call ""void C.Finally3(int)"" - IL_000f: nop - IL_0010: nop - IL_0011: ret -} -"); - - v0.VerifyIL("C.d__0.System.IDisposable.Dispose", @" -{ - // Code size 33 (0x21) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -3 - IL_000a: beq.s IL_0014 - IL_000c: br.s IL_000e - IL_000e: ldloc.0 - IL_000f: ldc.i4.2 - IL_0010: beq.s IL_0014 - IL_0012: br.s IL_0020 - IL_0014: nop - .try - { - IL_0015: leave.s IL_001e - } - finally - { - IL_0017: ldarg.0 - IL_0018: call ""void C.d__0.<>m__Finally1()"" - IL_001d: endfinally - } - IL_001e: br.s IL_0020 - IL_0020: ret -} -"); - diff1.VerifyIL("C.d__0.System.IDisposable.Dispose", @" -{ - // Code size 108 (0x6c) + // Code size 69 (0x45) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__0.<>1__state"" IL_0006: stloc.0 IL_0007: ldloc.0 - IL_0008: ldc.i4.s -5 - IL_000a: sub - IL_000b: switch ( - IL_0046, - IL_003a, - IL_0046, - IL_006b, - IL_006b, - IL_006b, - IL_003a, - IL_0046, - IL_006b, - IL_0046) - IL_0038: br.s IL_006b - IL_003a: nop - .try - { - IL_003b: leave.s IL_0044 - } - finally - { - IL_003d: ldarg.0 - IL_003e: call ""void C.d__0.<>m__Finally2()"" - IL_0043: endfinally - } - IL_0044: br.s IL_006b - IL_0046: nop - .try - { - IL_0047: ldloc.0 - IL_0048: ldc.i4.s -5 - IL_004a: beq.s IL_0054 - IL_004c: br.s IL_004e - IL_004e: ldloc.0 - IL_004f: ldc.i4.4 - IL_0050: beq.s IL_0054 - IL_0052: br.s IL_0060 - IL_0054: nop - .try - { - IL_0055: leave.s IL_005e - } - finally - { - IL_0057: ldarg.0 - IL_0058: call ""void C.d__0.<>m__Finally3()"" - IL_005d: endfinally - } - IL_005e: br.s IL_0060 - IL_0060: leave.s IL_0069 - } - finally - { - IL_0062: ldarg.0 - IL_0063: call ""void C.d__0.<>m__Finally1()"" - IL_0068: endfinally - } - IL_0069: br.s IL_006b - IL_006b: ret -} -"); - - v0.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 179 (0xb3) - .maxstack 2 - .locals init (bool V_0, - int V_1) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: switch ( - IL_001f, - IL_0021, - IL_0023, - IL_0025) - IL_001d: br.s IL_0027 - IL_001f: br.s IL_002e - IL_0021: br.s IL_004c - IL_0023: br.s IL_0072 - IL_0025: br.s IL_0098 - IL_0027: ldc.i4.0 - IL_0028: stloc.0 - IL_0029: leave IL_00b1 - IL_002e: ldarg.0 - IL_002f: ldc.i4.m1 - IL_0030: stfld ""int C.d__0.<>1__state"" - IL_0035: nop - IL_0036: ldarg.0 - IL_0037: call ""int C.M1()"" - IL_003c: stfld ""int C.d__0.<>2__current"" - IL_0041: ldarg.0 - IL_0042: ldc.i4.1 - IL_0043: stfld ""int C.d__0.<>1__state"" - IL_0048: ldc.i4.1 - IL_0049: stloc.0 - IL_004a: leave.s IL_00b1 - IL_004c: ldarg.0 - IL_004d: ldc.i4.m1 - IL_004e: stfld ""int C.d__0.<>1__state"" - IL_0053: ldarg.0 - IL_0054: ldc.i4.s -3 - IL_0056: stfld ""int C.d__0.<>1__state"" - IL_005b: nop - IL_005c: ldarg.0 - IL_005d: call ""int C.M2()"" - IL_0062: stfld ""int C.d__0.<>2__current"" - IL_0067: ldarg.0 - IL_0068: ldc.i4.2 - IL_0069: stfld ""int C.d__0.<>1__state"" - IL_006e: ldc.i4.1 - IL_006f: stloc.0 - IL_0070: leave.s IL_00b1 - IL_0072: ldarg.0 - IL_0073: ldc.i4.s -3 - IL_0075: stfld ""int C.d__0.<>1__state"" - IL_007a: nop - IL_007b: ldarg.0 - IL_007c: call ""void C.d__0.<>m__Finally1()"" - IL_0081: nop - IL_0082: ldarg.0 - IL_0083: call ""int C.M3()"" - IL_0088: stfld ""int C.d__0.<>2__current"" - IL_008d: ldarg.0 - IL_008e: ldc.i4.3 - IL_008f: stfld ""int C.d__0.<>1__state"" - IL_0094: ldc.i4.1 - IL_0095: stloc.0 - IL_0096: leave.s IL_00b1 - IL_0098: ldarg.0 - IL_0099: ldc.i4.m1 - IL_009a: stfld ""int C.d__0.<>1__state"" - IL_009f: call ""void C.End()"" - IL_00a4: nop - IL_00a5: ldc.i4.0 - IL_00a6: stloc.0 - IL_00a7: leave.s IL_00b1 - } - fault - { - IL_00a9: ldarg.0 - IL_00aa: call ""void C.d__0.Dispose()"" - IL_00af: nop - IL_00b0: endfinally - } - IL_00b1: ldloc.0 - IL_00b2: ret -} -"); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 259 (0x103) - .maxstack 2 - .locals init (bool V_0, - int V_1) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: switch ( - IL_0023, - IL_0025, - IL_0027, - IL_0029, - IL_002e) - IL_0021: br.s IL_0033 - IL_0023: br.s IL_003a - IL_0025: br.s IL_0064 - IL_0027: br.s IL_0093 - IL_0029: br IL_00e8 - IL_002e: br IL_00ba - IL_0033: ldc.i4.0 - IL_0034: stloc.0 - IL_0035: leave IL_0101 - IL_003a: ldarg.0 - IL_003b: ldc.i4.m1 - IL_003c: stfld ""int C.d__0.<>1__state"" - IL_0041: nop - IL_0042: ldarg.0 - IL_0043: ldc.i4.s -4 - IL_0045: stfld ""int C.d__0.<>1__state"" - IL_004a: nop - IL_004b: ldarg.0 - IL_004c: call ""int C.M1()"" - IL_0051: stfld ""int C.d__0.<>2__current"" - IL_0056: ldarg.0 - IL_0057: ldc.i4.1 - IL_0058: stfld ""int C.d__0.<>1__state"" - IL_005d: ldc.i4.1 - IL_005e: stloc.0 - IL_005f: leave IL_0101 - IL_0064: ldarg.0 - IL_0065: ldc.i4.s -4 - IL_0067: stfld ""int C.d__0.<>1__state"" - IL_006c: nop - IL_006d: ldarg.0 - IL_006e: call ""void C.d__0.<>m__Finally2()"" - IL_0073: nop - IL_0074: ldarg.0 - IL_0075: ldc.i4.s -3 - IL_0077: stfld ""int C.d__0.<>1__state"" - IL_007c: nop - IL_007d: ldarg.0 - IL_007e: call ""int C.M2()"" - IL_0083: stfld ""int C.d__0.<>2__current"" - IL_0088: ldarg.0 - IL_0089: ldc.i4.2 - IL_008a: stfld ""int C.d__0.<>1__state"" - IL_008f: ldc.i4.1 - IL_0090: stloc.0 - IL_0091: leave.s IL_0101 - IL_0093: ldarg.0 - IL_0094: ldc.i4.s -3 - IL_0096: stfld ""int C.d__0.<>1__state"" - IL_009b: ldarg.0 - IL_009c: ldc.i4.s -5 - IL_009e: stfld ""int C.d__0.<>1__state"" - IL_00a3: nop - IL_00a4: ldarg.0 - IL_00a5: call ""int C.M4()"" - IL_00aa: stfld ""int C.d__0.<>2__current"" - IL_00af: ldarg.0 - IL_00b0: ldc.i4.4 - IL_00b1: stfld ""int C.d__0.<>1__state"" - IL_00b6: ldc.i4.1 - IL_00b7: stloc.0 - IL_00b8: leave.s IL_0101 - IL_00ba: ldarg.0 - IL_00bb: ldc.i4.s -5 - IL_00bd: stfld ""int C.d__0.<>1__state"" - IL_00c2: nop - IL_00c3: ldarg.0 - IL_00c4: call ""void C.d__0.<>m__Finally3()"" - IL_00c9: nop - IL_00ca: nop - IL_00cb: ldarg.0 - IL_00cc: call ""void C.d__0.<>m__Finally1()"" - IL_00d1: nop - IL_00d2: ldarg.0 - IL_00d3: call ""int C.M3()"" - IL_00d8: stfld ""int C.d__0.<>2__current"" - IL_00dd: ldarg.0 - IL_00de: ldc.i4.3 - IL_00df: stfld ""int C.d__0.<>1__state"" - IL_00e4: ldc.i4.1 - IL_00e5: stloc.0 - IL_00e6: leave.s IL_0101 - IL_00e8: ldarg.0 - IL_00e9: ldc.i4.m1 - IL_00ea: stfld ""int C.d__0.<>1__state"" - IL_00ef: call ""void C.End()"" - IL_00f4: nop - IL_00f5: ldc.i4.0 - IL_00f6: stloc.0 - IL_00f7: leave.s IL_0101 - } - fault - { - IL_00f9: ldarg.0 - IL_00fa: call ""void C.d__0.Dispose()"" - IL_00ff: nop - IL_0100: endfinally - } - IL_0101: ldloc.0 - IL_0102: ret + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0016 + IL_0012: br.s IL_0018 + IL_0014: br.s IL_003c + IL_0016: ldc.i4.0 + IL_0017: ret + IL_0018: ldarg.0 + IL_0019: ldc.i4.m1 + IL_001a: stfld ""int C.d__0.<>1__state"" + IL_001f: nop + IL_0020: ldarg.0 + IL_0021: ldarg.0 + IL_0022: ldfld ""int C.d__0.p"" + IL_0027: stfld ""int C.d__0.5__1"" + IL_002c: ldarg.0 + IL_002d: ldc.i4.2 + IL_002e: stfld ""int C.d__0.<>2__current"" + IL_0033: ldarg.0 + IL_0034: ldc.i4.1 + IL_0035: stfld ""int C.d__0.<>1__state"" + IL_003a: ldc.i4.1 + IL_003b: ret + IL_003c: ldarg.0 + IL_003d: ldc.i4.m1 + IL_003e: stfld ""int C.d__0.<>1__state"" + IL_0043: ldc.i4.0 + IL_0044: ret }"); + } + } } [Fact] - public void UpdateIterator_YieldReturn_Add_Finally_UsingDeclaration() + public void UpdateIterator_UserDefinedVariables_AddVariable() { - var source0 = MarkedSource(@" + var source0 = @" using System; using System.Collections.Generic; class C { - static IEnumerable F() + static IEnumerable F(int p) { - using var x = M1(); - yield return M2(); - End(); + int x = p; + yield return x; } - - static IDisposable M1() => null; - static int M2() => 0; - static int M3() => 0; - static void End() {} -}"); - var source1 = MarkedSource(@" +}"; + var source1 = @" using System; using System.Collections.Generic; class C { - static IEnumerable F() + static IEnumerable F(int p) { - using var x = M1(); - yield return M2(); - yield return M3(); - End(); + int y = 1234; + int x = p; + yield return y; + Console.WriteLine(x); } - - static IDisposable M1() => null; - static int M2() => 0; - static int M3() => 0; - static void End() {} -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemCoreRef, CSharpRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); +}"; + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll); + var compilation1 = compilation0.WithSource(source1); var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); + var symReader = v0.CreateSymReader(); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - - - -"); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetEquivalentNodesMap(method1, method0), preserveLocalVariables: true))); - diff1.VerifySynthesizedMembers( - "C: {d__0}", - "C.d__0: {" + string.Join(", ", new[] - { - "<>1__state", - "<>2__current", - "<>l__initialThreadId", - "5__1", - "System.IDisposable.Dispose", - "MoveNext", - "<>m__Finally1", - "System.Collections.Generic.IEnumerator.get_Current", - "System.Collections.IEnumerator.Reset, System.Collections.IEnumerator.get_Current", - "System.Collections.Generic.IEnumerable.GetEnumerator", - "System.Collections.IEnumerable.GetEnumerator", - "System.Collections.Generic.IEnumerator.Current", - "System.Collections.IEnumerator.Current" - }) + "}"); - - diff1.VerifyIL("C.d__0.<>m__Finally1", @" -{ - // Code size 28 (0x1c) - .maxstack 2 - IL_0000: ldarg.0 - IL_0001: ldc.i4.m1 - IL_0002: stfld ""int C.d__0.<>1__state"" - IL_0007: ldarg.0 - IL_0008: ldfld ""System.IDisposable C.d__0.5__1"" - IL_000d: brfalse.s IL_001b - IL_000f: ldarg.0 - IL_0010: ldfld ""System.IDisposable C.d__0.5__1"" - IL_0015: callvirt ""void System.IDisposable.Dispose()"" - IL_001a: nop - IL_001b: ret -} -"); + // Verify delta metadata contains expected rows. + using (var md1 = diff1.GetMetadata()) + { + // 1 field def added & 3 methods updated + CheckEncLogDefinitions(md1.Reader, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(7, TableIndex.Field, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - v0.VerifyIL("C.d__0.System.IDisposable.Dispose", @" -{ - // Code size 33 (0x21) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -3 - IL_000a: beq.s IL_0014 - IL_000c: br.s IL_000e - IL_000e: ldloc.0 - IL_000f: ldc.i4.1 - IL_0010: beq.s IL_0014 - IL_0012: br.s IL_0020 - IL_0014: nop - .try - { - IL_0015: leave.s IL_001e - } - finally - { - IL_0017: ldarg.0 - IL_0018: call ""void C.d__0.<>m__Finally1()"" - IL_001d: endfinally - } - IL_001e: br.s IL_0020 - IL_0020: ret -} -"); - diff1.VerifyIL("C.d__0.System.IDisposable.Dispose", @" + diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" { - // Code size 35 (0x23) + // Code size 97 (0x61) .maxstack 2 .locals init (int V_0) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__0.<>1__state"" IL_0006: stloc.0 IL_0007: ldloc.0 - IL_0008: ldc.i4.s -3 - IL_000a: beq.s IL_0016 - IL_000c: br.s IL_000e - IL_000e: ldloc.0 - IL_000f: ldc.i4.1 - IL_0010: sub - IL_0011: ldc.i4.1 - IL_0012: ble.un.s IL_0016 - IL_0014: br.s IL_0022 - IL_0016: nop - .try - { - IL_0017: leave.s IL_0020 - } - finally - { - IL_0019: ldarg.0 - IL_001a: call ""void C.d__0.<>m__Finally1()"" - IL_001f: endfinally - } - IL_0020: br.s IL_0022 - IL_0022: ret -} -"); - - v0.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" - { - // Code size 112 (0x70) - .maxstack 2 - .locals init (bool V_0, - int V_1) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: brfalse.s IL_0012 - IL_000a: br.s IL_000c - IL_000c: ldloc.1 - IL_000d: ldc.i4.1 - IL_000e: beq.s IL_0014 - IL_0010: br.s IL_0016 - IL_0012: br.s IL_001a - IL_0014: br.s IL_004b - IL_0016: ldc.i4.0 - IL_0017: stloc.0 - IL_0018: leave.s IL_006e - IL_001a: ldarg.0 - IL_001b: ldc.i4.m1 - IL_001c: stfld ""int C.d__0.<>1__state"" - IL_0021: nop - IL_0022: ldarg.0 - IL_0023: call ""System.IDisposable C.M1()"" - IL_0028: stfld ""System.IDisposable C.d__0.5__1"" - IL_002d: ldarg.0 - IL_002e: ldc.i4.s -3 - IL_0030: stfld ""int C.d__0.<>1__state"" - IL_0035: ldarg.0 - IL_0036: call ""int C.M2()"" - IL_003b: stfld ""int C.d__0.<>2__current"" - IL_0040: ldarg.0 - IL_0041: ldc.i4.1 - IL_0042: stfld ""int C.d__0.<>1__state"" - IL_0047: ldc.i4.1 - IL_0048: stloc.0 - IL_0049: leave.s IL_006e - IL_004b: ldarg.0 - IL_004c: ldc.i4.s -3 - IL_004e: stfld ""int C.d__0.<>1__state"" - IL_0053: call ""void C.End()"" - IL_0058: nop - IL_0059: ldc.i4.0 - IL_005a: stloc.0 - IL_005b: br.s IL_005d - IL_005d: ldarg.0 - IL_005e: call ""void C.d__0.<>m__Finally1()"" - IL_0063: nop - IL_0064: leave.s IL_006e - } - fault - { - IL_0066: ldarg.0 - IL_0067: call ""void C.d__0.Dispose()"" - IL_006c: nop - IL_006d: endfinally - } - IL_006e: ldloc.0 - IL_006f: ret -} -"); - - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" -{ - // Code size 153 (0x99) - .maxstack 2 - .locals init (bool V_0, - int V_1) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: switch ( - IL_001b, - IL_001d, - IL_001f) - IL_0019: br.s IL_0021 - IL_001b: br.s IL_0025 - IL_001d: br.s IL_0056 - IL_001f: br.s IL_0074 - IL_0021: ldc.i4.0 - IL_0022: stloc.0 - IL_0023: leave.s IL_0097 - IL_0025: ldarg.0 - IL_0026: ldc.i4.m1 - IL_0027: stfld ""int C.d__0.<>1__state"" - IL_002c: nop - IL_002d: ldarg.0 - IL_002e: call ""System.IDisposable C.M1()"" - IL_0033: stfld ""System.IDisposable C.d__0.5__1"" - IL_0038: ldarg.0 - IL_0039: ldc.i4.s -3 - IL_003b: stfld ""int C.d__0.<>1__state"" - IL_0040: ldarg.0 - IL_0041: call ""int C.M2()"" - IL_0046: stfld ""int C.d__0.<>2__current"" - IL_004b: ldarg.0 - IL_004c: ldc.i4.1 - IL_004d: stfld ""int C.d__0.<>1__state"" - IL_0052: ldc.i4.1 - IL_0053: stloc.0 - IL_0054: leave.s IL_0097 - IL_0056: ldarg.0 - IL_0057: ldc.i4.s -3 - IL_0059: stfld ""int C.d__0.<>1__state"" - IL_005e: ldarg.0 - IL_005f: call ""int C.M3()"" - IL_0064: stfld ""int C.d__0.<>2__current"" - IL_0069: ldarg.0 - IL_006a: ldc.i4.2 - IL_006b: stfld ""int C.d__0.<>1__state"" - IL_0070: ldc.i4.1 - IL_0071: stloc.0 - IL_0072: leave.s IL_0097 - IL_0074: ldarg.0 - IL_0075: ldc.i4.s -3 - IL_0077: stfld ""int C.d__0.<>1__state"" - IL_007c: call ""void C.End()"" - IL_0081: nop - IL_0082: ldc.i4.0 - IL_0083: stloc.0 - IL_0084: br.s IL_0086 - IL_0086: ldarg.0 - IL_0087: call ""void C.d__0.<>m__Finally1()"" - IL_008c: nop - IL_008d: leave.s IL_0097 - } - fault - { - IL_008f: ldarg.0 - IL_0090: call ""void C.d__0.Dispose()"" - IL_0095: nop - IL_0096: endfinally - } - IL_0097: ldloc.0 - IL_0098: ret + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0016 + IL_0012: br.s IL_0018 + IL_0014: br.s IL_004c + IL_0016: ldc.i4.0 + IL_0017: ret + IL_0018: ldarg.0 + IL_0019: ldc.i4.m1 + IL_001a: stfld ""int C.d__0.<>1__state"" + IL_001f: nop + IL_0020: ldarg.0 + IL_0021: ldc.i4 0x4d2 + IL_0026: stfld ""int C.d__0.5__2"" + IL_002b: ldarg.0 + IL_002c: ldarg.0 + IL_002d: ldfld ""int C.d__0.p"" + IL_0032: stfld ""int C.d__0.5__1"" + IL_0037: ldarg.0 + IL_0038: ldarg.0 + IL_0039: ldfld ""int C.d__0.5__2"" + IL_003e: stfld ""int C.d__0.<>2__current"" + IL_0043: ldarg.0 + IL_0044: ldc.i4.1 + IL_0045: stfld ""int C.d__0.<>1__state"" + IL_004a: ldc.i4.1 + IL_004b: ret + IL_004c: ldarg.0 + IL_004d: ldc.i4.m1 + IL_004e: stfld ""int C.d__0.<>1__state"" + IL_0053: ldarg.0 + IL_0054: ldfld ""int C.d__0.5__1"" + IL_0059: call ""void System.Console.WriteLine(int)"" + IL_005e: nop + IL_005f: ldc.i4.0 + IL_0060: ret }"); + } + } } [Fact] - public void UpdateIterator_YieldReturn_Add_Finally_Foreach_ForEachVar_Using_Lock() + public void UpdateIterator_UserDefinedVariables_AddAndRemoveVariable() { - var source0 = MarkedSource(@" + var source0 = @" using System; using System.Collections.Generic; class C { - static IEnumerable F() + static IEnumerable F(int p) { - using IDisposable x1 = D(), x2 = D(); - - using (D()) - using (IDisposable y1 = D(), y2 = D()) - foreach (var z in E()) - foreach (var (u, w) in E()) - lock (D()) - { - yield return 1; - } + int x = p; + yield return x; } - - static IDisposable D() => null; - static IEnumerable<(int, int)> E() => null; -}"); - var source1 = MarkedSource(@" +}"; + var source1 = @" using System; using System.Collections.Generic; class C { - static IEnumerable F() + static IEnumerable F(int p) { - using IDisposable x1 = D(), x2 = D(); - - using (D()) - using (IDisposable y1 = D(), y2 = D()) - foreach (var z in E()) - foreach (var (u, w) in E()) - lock (D()) - { - yield return 1; - yield return 2; - } + int y = 1234; + yield return y; + Console.WriteLine(p); } - - static IDisposable D() => null; - static IEnumerable<(int, int)> E() => null; -}"); - var compilation0 = CreateCompilationWithMscorlib45(new[] { source0.Tree }, new[] { SystemRuntimeFacadeRef, ValueTupleRef }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(source1.Tree); +}"; + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll); + var compilation1 = compilation0.WithSource(source1); var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); + var symReader = v0.CreateSymReader(); - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetEquivalentNodesMap(method1, method0), preserveLocalVariables: true))); - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"); + // Verify delta metadata contains expected rows. + using (var md1 = diff1.GetMetadata()) + { + // 1 field def added & 3 methods updated + CheckEncLogDefinitions(md1.Reader, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(7, TableIndex.Field, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.Param, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" + diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" { - // Code size 526 (0x20e) + // Code size 85 (0x55) .maxstack 2 - .locals init (bool V_0, - int V_1, - System.ValueTuple V_2) - .try - { - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.1 - IL_0007: ldloc.1 - IL_0008: switch ( - IL_001b, - IL_001d, - IL_0022) - IL_0019: br.s IL_0027 - IL_001b: br.s IL_002e - IL_001d: br IL_0148 - IL_0022: br IL_0165 - IL_0027: ldc.i4.0 - IL_0028: stloc.0 - IL_0029: leave IL_020c - IL_002e: ldarg.0 - IL_002f: ldc.i4.m1 - IL_0030: stfld ""int C.d__0.<>1__state"" - IL_0035: nop - IL_0036: ldarg.0 - IL_0037: call ""System.IDisposable C.D()"" - IL_003c: stfld ""System.IDisposable C.d__0.5__1"" - IL_0041: ldarg.0 - IL_0042: ldc.i4.s -3 - IL_0044: stfld ""int C.d__0.<>1__state"" - IL_0049: ldarg.0 - IL_004a: call ""System.IDisposable C.D()"" - IL_004f: stfld ""System.IDisposable C.d__0.5__2"" - IL_0054: ldarg.0 - IL_0055: ldc.i4.s -4 - IL_0057: stfld ""int C.d__0.<>1__state"" - IL_005c: ldarg.0 - IL_005d: call ""System.IDisposable C.D()"" - IL_0062: stfld ""System.IDisposable C.d__0.<>s__3"" - IL_0067: ldarg.0 - IL_0068: ldc.i4.s -5 - IL_006a: stfld ""int C.d__0.<>1__state"" - IL_006f: ldarg.0 - IL_0070: call ""System.IDisposable C.D()"" - IL_0075: stfld ""System.IDisposable C.d__0.5__4"" - IL_007a: ldarg.0 - IL_007b: ldc.i4.s -6 - IL_007d: stfld ""int C.d__0.<>1__state"" - IL_0082: ldarg.0 - IL_0083: call ""System.IDisposable C.D()"" - IL_0088: stfld ""System.IDisposable C.d__0.5__5"" - IL_008d: ldarg.0 - IL_008e: ldc.i4.s -7 - IL_0090: stfld ""int C.d__0.<>1__state"" - IL_0095: nop - IL_0096: ldarg.0 - IL_0097: call ""System.Collections.Generic.IEnumerable> C.E()"" - IL_009c: callvirt ""System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator()"" - IL_00a1: stfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__6"" - IL_00a6: ldarg.0 - IL_00a7: ldc.i4.s -8 - IL_00a9: stfld ""int C.d__0.<>1__state"" - IL_00ae: br IL_01a6 - IL_00b3: ldarg.0 - IL_00b4: ldarg.0 - IL_00b5: ldfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__6"" - IL_00ba: callvirt ""System.ValueTuple System.Collections.Generic.IEnumerator>.Current.get"" - IL_00bf: stfld ""System.ValueTuple C.d__0.5__7"" - IL_00c4: nop - IL_00c5: ldarg.0 - IL_00c6: call ""System.Collections.Generic.IEnumerable> C.E()"" - IL_00cb: callvirt ""System.Collections.Generic.IEnumerator> System.Collections.Generic.IEnumerable>.GetEnumerator()"" - IL_00d0: stfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__8"" - IL_00d5: ldarg.0 - IL_00d6: ldc.i4.s -9 - IL_00d8: stfld ""int C.d__0.<>1__state"" - IL_00dd: br IL_017c - IL_00e2: ldarg.0 - IL_00e3: ldfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__8"" - IL_00e8: callvirt ""System.ValueTuple System.Collections.Generic.IEnumerator>.Current.get"" - IL_00ed: stloc.2 - IL_00ee: ldarg.0 - IL_00ef: ldloc.2 - IL_00f0: ldfld ""int System.ValueTuple.Item1"" - IL_00f5: stfld ""int C.d__0.5__13"" - IL_00fa: ldarg.0 - IL_00fb: ldloc.2 - IL_00fc: ldfld ""int System.ValueTuple.Item2"" - IL_0101: stfld ""int C.d__0.5__14"" - IL_0106: ldarg.0 - IL_0107: call ""System.IDisposable C.D()"" - IL_010c: stfld ""System.IDisposable C.d__0.<>s__11"" - IL_0111: ldarg.0 - IL_0112: ldc.i4.0 - IL_0113: stfld ""bool C.d__0.<>s__12"" - IL_0118: ldarg.0 - IL_0119: ldc.i4.s -10 - IL_011b: stfld ""int C.d__0.<>1__state"" - IL_0120: ldarg.0 - IL_0121: ldfld ""System.IDisposable C.d__0.<>s__11"" - IL_0126: ldarg.0 - IL_0127: ldflda ""bool C.d__0.<>s__12"" - IL_012c: call ""void System.Threading.Monitor.Enter(object, ref bool)"" - IL_0131: nop - IL_0132: nop - IL_0133: ldarg.0 - IL_0134: ldc.i4.1 - IL_0135: stfld ""int C.d__0.<>2__current"" - IL_013a: ldarg.0 - IL_013b: ldc.i4.1 - IL_013c: stfld ""int C.d__0.<>1__state"" - IL_0141: ldc.i4.1 - IL_0142: stloc.0 - IL_0143: leave IL_020c - IL_0148: ldarg.0 - IL_0149: ldc.i4.s -10 - IL_014b: stfld ""int C.d__0.<>1__state"" - IL_0150: ldarg.0 - IL_0151: ldc.i4.2 - IL_0152: stfld ""int C.d__0.<>2__current"" - IL_0157: ldarg.0 - IL_0158: ldc.i4.2 - IL_0159: stfld ""int C.d__0.<>1__state"" - IL_015e: ldc.i4.1 - IL_015f: stloc.0 - IL_0160: leave IL_020c - IL_0165: ldarg.0 - IL_0166: ldc.i4.s -10 - IL_0168: stfld ""int C.d__0.<>1__state"" - IL_016d: nop - IL_016e: ldarg.0 - IL_016f: call ""void C.d__0.<>m__Finally8()"" - IL_0174: nop - IL_0175: ldarg.0 - IL_0176: ldnull - IL_0177: stfld ""System.IDisposable C.d__0.<>s__11"" - IL_017c: ldarg.0 - IL_017d: ldfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__8"" - IL_0182: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" - IL_0187: brtrue IL_00e2 - IL_018c: ldarg.0 - IL_018d: call ""void C.d__0.<>m__Finally7()"" - IL_0192: nop - IL_0193: ldarg.0 - IL_0194: ldnull - IL_0195: stfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__8"" - IL_019a: ldarg.0 - IL_019b: ldflda ""System.ValueTuple C.d__0.5__7"" - IL_01a0: initobj ""System.ValueTuple"" - IL_01a6: ldarg.0 - IL_01a7: ldfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__6"" - IL_01ac: callvirt ""bool System.Collections.IEnumerator.MoveNext()"" - IL_01b1: brtrue IL_00b3 - IL_01b6: ldarg.0 - IL_01b7: call ""void C.d__0.<>m__Finally6()"" - IL_01bc: nop - IL_01bd: ldarg.0 - IL_01be: ldnull - IL_01bf: stfld ""System.Collections.Generic.IEnumerator> C.d__0.<>s__6"" - IL_01c4: ldarg.0 - IL_01c5: call ""void C.d__0.<>m__Finally5()"" - IL_01ca: nop - IL_01cb: ldarg.0 - IL_01cc: call ""void C.d__0.<>m__Finally4()"" - IL_01d1: nop - IL_01d2: ldarg.0 - IL_01d3: ldnull - IL_01d4: stfld ""System.IDisposable C.d__0.5__4"" - IL_01d9: ldarg.0 - IL_01da: ldnull - IL_01db: stfld ""System.IDisposable C.d__0.5__5"" - IL_01e0: ldarg.0 - IL_01e1: call ""void C.d__0.<>m__Finally3()"" - IL_01e6: nop - IL_01e7: ldarg.0 - IL_01e8: ldnull - IL_01e9: stfld ""System.IDisposable C.d__0.<>s__3"" - IL_01ee: ldc.i4.0 - IL_01ef: stloc.0 - IL_01f0: br.s IL_01f2 - IL_01f2: ldarg.0 - IL_01f3: call ""void C.d__0.<>m__Finally2()"" - IL_01f8: nop - IL_01f9: br.s IL_01fb - IL_01fb: ldarg.0 - IL_01fc: call ""void C.d__0.<>m__Finally1()"" - IL_0201: nop - IL_0202: leave.s IL_020c - } - fault - { - IL_0204: ldarg.0 - IL_0205: call ""void C.d__0.Dispose()"" - IL_020a: nop - IL_020b: endfinally - } - IL_020c: ldloc.0 - IL_020d: ret + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__0.<>1__state"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0016 + IL_0012: br.s IL_0018 + IL_0014: br.s IL_0040 + IL_0016: ldc.i4.0 + IL_0017: ret + IL_0018: ldarg.0 + IL_0019: ldc.i4.m1 + IL_001a: stfld ""int C.d__0.<>1__state"" + IL_001f: nop + IL_0020: ldarg.0 + IL_0021: ldc.i4 0x4d2 + IL_0026: stfld ""int C.d__0.5__2"" + IL_002b: ldarg.0 + IL_002c: ldarg.0 + IL_002d: ldfld ""int C.d__0.5__2"" + IL_0032: stfld ""int C.d__0.<>2__current"" + IL_0037: ldarg.0 + IL_0038: ldc.i4.1 + IL_0039: stfld ""int C.d__0.<>1__state"" + IL_003e: ldc.i4.1 + IL_003f: ret + IL_0040: ldarg.0 + IL_0041: ldc.i4.m1 + IL_0042: stfld ""int C.d__0.<>1__state"" + IL_0047: ldarg.0 + IL_0048: ldfld ""int C.d__0.p"" + IL_004d: call ""void System.Console.WriteLine(int)"" + IL_0052: nop + IL_0053: ldc.i4.0 + IL_0054: ret }"); + } + } } [Fact] - public void UpdateAsyncEnumerable_AwaitAndYield_AddAndRemove() + public void UpdateIterator_UserDefinedVariables_ChangeVariableType() { - var source0 = MarkedSource(@" + var source0 = @" +using System; using System.Collections.Generic; -using System.Threading.Tasks; class C { - async IAsyncEnumerable F() + static IEnumerable F() { - yield return F1(); - await Task.FromResult(1); - End(); + var x = 1; + yield return 1; + Console.WriteLine(x); } - - static int F1() => 1; - static int F2() => 1; - static void End() { } -} -"); - var source1 = MarkedSource(@" +}"; + var source1 = @" +using System; using System.Collections.Generic; -using System.Threading.Tasks; class C { - async IAsyncEnumerable F() + static IEnumerable F() { - yield return F2(); - await Task.FromResult(2); - yield return F1(); - await Task.FromResult(1); - End(); + var x = 1.0; + yield return 2; + Console.WriteLine(x); } +}"; + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll); + var compilation1 = compilation0.WithSource(source1); - static int F1() => 1; - static int F2() => 1; - static void End() { } -}"); - var source2 = MarkedSource(@" -using System.Collections.Generic; -using System.Threading.Tasks; + var v0 = CompileAndVerify(compilation0); + var symReader = v0.CreateSymReader(); -class C -{ - async IAsyncEnumerable F() - { - yield return F2(); - await Task.FromResult(2); - await Task.FromResult(1); - End(); - } + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); + + var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetEquivalentNodesMap(method1, method0), preserveLocalVariables: true))); + + // Verify delta metadata contains expected rows. + using (var md1 = diff1.GetMetadata()) + { + // 1 field def added & 3 methods updated + CheckEncLogDefinitions(md1.Reader, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(5, TableIndex.Field, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); - static int F1() => 1; - static int F2() => 1; - static void End() { } + diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" +{ + // Code size 84 (0x54) + .maxstack 2 + .locals init (int V_0) + IL_0000: ldarg.0 + IL_0001: ldfld ""int C.d__0.<>1__state"" + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0016 + IL_0012: br.s IL_0018 + IL_0014: br.s IL_003f + IL_0016: ldc.i4.0 + IL_0017: ret + IL_0018: ldarg.0 + IL_0019: ldc.i4.m1 + IL_001a: stfld ""int C.d__0.<>1__state"" + IL_001f: nop + IL_0020: ldarg.0 + IL_0021: ldc.r8 1 + IL_002a: stfld ""double C.d__0.5__2"" + IL_002f: ldarg.0 + IL_0030: ldc.i4.2 + IL_0031: stfld ""int C.d__0.<>2__current"" + IL_0036: ldarg.0 + IL_0037: ldc.i4.1 + IL_0038: stfld ""int C.d__0.<>1__state"" + IL_003d: ldc.i4.1 + IL_003e: ret + IL_003f: ldarg.0 + IL_0040: ldc.i4.m1 + IL_0041: stfld ""int C.d__0.<>1__state"" + IL_0046: ldarg.0 + IL_0047: ldfld ""double C.d__0.5__2"" + IL_004c: call ""void System.Console.WriteLine(double)"" + IL_0051: nop + IL_0052: ldc.i4.0 + IL_0053: ret }"); - var source3 = MarkedSource(@" + } + } + } + + [Fact] + public void UpdateIterator_SynthesizedVariables_ChangeVariableType() + { + var source0 = @" +using System; using System.Collections.Generic; -using System.Threading.Tasks; class C { - async IAsyncEnumerable F() + static IEnumerable F() { - yield return F2(); - await Task.FromResult(1); - End(); + foreach (object item in new[] { 1 }) { yield return 1; } } +}"; + var source1 = @" +using System; +using System.Collections.Generic; - static int F1() => 1; - static int F2() => 1; - static void End() { } -}"); - var asyncStreamsTree = Parse(AsyncStreamsTypes); - - var compilation0 = CreateCompilationWithTasksExtensions(new[] { source0.Tree, asyncStreamsTree }, options: ComSafeDebugDll); - var compilation1 = compilation0.WithSource(new[] { source1.Tree, asyncStreamsTree }); - var compilation2 = compilation1.WithSource(new[] { source2.Tree, asyncStreamsTree }); - var compilation3 = compilation2.WithSource(new[] { source3.Tree, asyncStreamsTree }); - - var v0 = CompileAndVerify(compilation0); - v0.VerifyDiagnostics(); - var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - - var f0 = compilation0.GetMember("C.F"); - var f1 = compilation1.GetMember("C.F"); - var f2 = compilation2.GetMember("C.F"); - var f3 = compilation3.GetMember("C.F"); - - var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); +class C +{ + static IEnumerable F() + { + foreach (object item in new[] { 1.0 }) { yield return 1; } + } +}"; + // Rude edit but the compiler should handle it. - var diff1 = compilation1.EmitDifference( - generation0, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapFromMarkers(source0, source1), preserveLocalVariables: true))); + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + var compilation1 = compilation0.WithSource(source1); - var diff2 = compilation2.EmitDifference( - diff1.NextGeneration, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f1, f2, GetSyntaxMapFromMarkers(source1, source2), preserveLocalVariables: true))); + var v0 = CompileAndVerify(compilation0, symbolValidator: module => + { + Assert.Equal(new[] + { + "<>1__state: int", + "<>2__current: int", + "<>l__initialThreadId: int", + "<>s__1: int[]", + "<>s__2: int", + "5__3: object" + }, module.GetFieldNamesAndTypes("C.d__0")); + }); - var diff3 = compilation3.EmitDifference( - diff2.NextGeneration, - ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f2, f3, GetSyntaxMapFromMarkers(source2, source3), preserveLocalVariables: true))); + var symReader = v0.CreateSymReader(); - v0.VerifyPdb("C.F", @" - - - - - - - - - - - - - - - - -"); + using (var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData)) + { + var method0 = compilation0.GetMember("C.F"); + var method1 = compilation1.GetMember("C.F"); - diff1.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 484 (0x1e4) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -5 - IL_000a: sub - IL_000b: switch ( - IL_002e, - IL_0030, - IL_0035, - IL_0041, - IL_0041, - IL_0037, - IL_003c) - IL_002c: br.s IL_0041 - IL_002e: br.s IL_0072 - IL_0030: br IL_0102 - IL_0035: br.s IL_0041 - IL_0037: br IL_0154 - IL_003c: br IL_00c4 - IL_0041: ldarg.0 - IL_0042: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0047: brfalse.s IL_004e - IL_0049: leave IL_01ad - IL_004e: ldarg.0 - IL_004f: ldc.i4.m1 - IL_0050: dup - IL_0051: stloc.0 - IL_0052: stfld ""int C.d__0.<>1__state"" - IL_0057: nop - IL_0058: ldarg.0 - IL_0059: call ""int C.F2()"" - IL_005e: stfld ""int C.d__0.<>2__current"" - IL_0063: ldarg.0 - IL_0064: ldc.i4.s -5 - IL_0066: dup - IL_0067: stloc.0 - IL_0068: stfld ""int C.d__0.<>1__state"" - IL_006d: leave IL_01d6 - IL_0072: ldarg.0 - IL_0073: ldc.i4.m1 - IL_0074: dup - IL_0075: stloc.0 - IL_0076: stfld ""int C.d__0.<>1__state"" - IL_007b: ldarg.0 - IL_007c: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0081: brfalse.s IL_0088 - IL_0083: leave IL_01ad - IL_0088: ldc.i4.2 - IL_0089: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.FromResult(int)"" - IL_008e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0093: stloc.1 - IL_0094: ldloca.s V_1 - IL_0096: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_009b: brtrue.s IL_00e0 - IL_009d: ldarg.0 - IL_009e: ldc.i4.1 - IL_009f: dup - IL_00a0: stloc.0 - IL_00a1: stfld ""int C.d__0.<>1__state"" - IL_00a6: ldarg.0 - IL_00a7: ldloc.1 - IL_00a8: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00ad: ldarg.0 - IL_00ae: stloc.2 - IL_00af: ldarg.0 - IL_00b0: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_00b5: ldloca.s V_1 - IL_00b7: ldloca.s V_2 - IL_00b9: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted, C.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_00be: nop - IL_00bf: leave IL_01e3 - IL_00c4: ldarg.0 - IL_00c5: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00ca: stloc.1 - IL_00cb: ldarg.0 - IL_00cc: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00d1: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00d7: ldarg.0 - IL_00d8: ldc.i4.m1 - IL_00d9: dup - IL_00da: stloc.0 - IL_00db: stfld ""int C.d__0.<>1__state"" - IL_00e0: ldloca.s V_1 - IL_00e2: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00e7: pop - IL_00e8: ldarg.0 - IL_00e9: call ""int C.F1()"" - IL_00ee: stfld ""int C.d__0.<>2__current"" - IL_00f3: ldarg.0 - IL_00f4: ldc.i4.s -4 - IL_00f6: dup - IL_00f7: stloc.0 - IL_00f8: stfld ""int C.d__0.<>1__state"" - IL_00fd: leave IL_01d6 - IL_0102: ldarg.0 - IL_0103: ldc.i4.m1 - IL_0104: dup - IL_0105: stloc.0 - IL_0106: stfld ""int C.d__0.<>1__state"" - IL_010b: ldarg.0 - IL_010c: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0111: brfalse.s IL_0118 - IL_0113: leave IL_01ad - IL_0118: ldc.i4.1 - IL_0119: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.FromResult(int)"" - IL_011e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0123: stloc.3 - IL_0124: ldloca.s V_3 - IL_0126: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_012b: brtrue.s IL_0170 - IL_012d: ldarg.0 - IL_012e: ldc.i4.0 - IL_012f: dup - IL_0130: stloc.0 - IL_0131: stfld ""int C.d__0.<>1__state"" - IL_0136: ldarg.0 - IL_0137: ldloc.3 - IL_0138: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_013d: ldarg.0 - IL_013e: stloc.2 - IL_013f: ldarg.0 - IL_0140: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_0145: ldloca.s V_3 - IL_0147: ldloca.s V_2 - IL_0149: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted, C.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_014e: nop - IL_014f: leave IL_01e3 - IL_0154: ldarg.0 - IL_0155: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_015a: stloc.3 - IL_015b: ldarg.0 - IL_015c: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_0161: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0167: ldarg.0 - IL_0168: ldc.i4.m1 - IL_0169: dup - IL_016a: stloc.0 - IL_016b: stfld ""int C.d__0.<>1__state"" - IL_0170: ldloca.s V_3 - IL_0172: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0177: pop - IL_0178: call ""void C.End()"" - IL_017d: nop - IL_017e: leave.s IL_01ad - } - catch System.Exception - { - IL_0180: stloc.s V_4 - IL_0182: ldarg.0 - IL_0183: ldc.i4.s -2 - IL_0185: stfld ""int C.d__0.<>1__state"" - IL_018a: ldarg.0 - IL_018b: ldc.i4.0 - IL_018c: stfld ""int C.d__0.<>2__current"" - IL_0191: ldarg.0 - IL_0192: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_0197: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_019c: nop - IL_019d: ldarg.0 - IL_019e: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_01a3: ldloc.s V_4 - IL_01a5: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_01aa: nop - IL_01ab: leave.s IL_01e3 - } - IL_01ad: ldarg.0 - IL_01ae: ldc.i4.s -2 - IL_01b0: stfld ""int C.d__0.<>1__state"" - IL_01b5: ldarg.0 - IL_01b6: ldc.i4.0 - IL_01b7: stfld ""int C.d__0.<>2__current"" - IL_01bc: ldarg.0 - IL_01bd: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_01c2: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_01c7: nop - IL_01c8: ldarg.0 - IL_01c9: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_01ce: ldc.i4.0 - IL_01cf: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_01d4: nop - IL_01d5: ret - IL_01d6: ldarg.0 - IL_01d7: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_01dc: ldc.i4.1 - IL_01dd: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_01e2: nop - IL_01e3: ret -} -"); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, symReader.GetEncMethodDebugInfo); + var diff1 = compilation1.EmitDifference( + generation0, + ImmutableArray.Create(SemanticEdit.Create(SemanticEditKind.Update, method0, method1, GetSyntaxMapByKind(method0, SyntaxKind.ForEachStatement), preserveLocalVariables: true))); - diff2.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" -{ - // Code size 447 (0x1bf) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld ""int C.d__0.<>1__state"" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -5 - IL_000a: sub - IL_000b: switch ( - IL_002e, - IL_003c, - IL_0030, - IL_003c, - IL_003c, - IL_0032, - IL_0037) - IL_002c: br.s IL_003c - IL_002e: br.s IL_007d - IL_0030: br.s IL_004c - IL_0032: br IL_012f - IL_0037: br IL_00cf - IL_003c: ldloc.0 - IL_003d: ldc.i4.s -4 - IL_003f: bgt.s IL_004c - IL_0041: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedIteratorMethod + @""" - IL_0046: newobj ""System.InvalidOperationException..ctor(string)"" - IL_004b: throw - IL_004c: ldarg.0 - IL_004d: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0052: brfalse.s IL_0059 - IL_0054: leave IL_0188 - IL_0059: ldarg.0 - IL_005a: ldc.i4.m1 - IL_005b: dup - IL_005c: stloc.0 - IL_005d: stfld ""int C.d__0.<>1__state"" - IL_0062: nop - IL_0063: ldarg.0 - IL_0064: call ""int C.F2()"" - IL_0069: stfld ""int C.d__0.<>2__current"" - IL_006e: ldarg.0 - IL_006f: ldc.i4.s -5 - IL_0071: dup - IL_0072: stloc.0 - IL_0073: stfld ""int C.d__0.<>1__state"" - IL_0078: leave IL_01b1 - IL_007d: ldarg.0 - IL_007e: ldc.i4.m1 - IL_007f: dup - IL_0080: stloc.0 - IL_0081: stfld ""int C.d__0.<>1__state"" - IL_0086: ldarg.0 - IL_0087: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_008c: brfalse.s IL_0093 - IL_008e: leave IL_0188 - IL_0093: ldc.i4.2 - IL_0094: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.FromResult(int)"" - IL_0099: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_009e: stloc.1 - IL_009f: ldloca.s V_1 - IL_00a1: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_00a6: brtrue.s IL_00eb - IL_00a8: ldarg.0 - IL_00a9: ldc.i4.1 - IL_00aa: dup - IL_00ab: stloc.0 - IL_00ac: stfld ""int C.d__0.<>1__state"" - IL_00b1: ldarg.0 - IL_00b2: ldloc.1 - IL_00b3: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00b8: ldarg.0 - IL_00b9: stloc.2 - IL_00ba: ldarg.0 - IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_00c0: ldloca.s V_1 - IL_00c2: ldloca.s V_2 - IL_00c4: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted, C.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_00c9: nop - IL_00ca: leave IL_01be - IL_00cf: ldarg.0 - IL_00d0: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00d5: stloc.1 - IL_00d6: ldarg.0 - IL_00d7: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00dc: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00e2: ldarg.0 - IL_00e3: ldc.i4.m1 - IL_00e4: dup - IL_00e5: stloc.0 - IL_00e6: stfld ""int C.d__0.<>1__state"" - IL_00eb: ldloca.s V_1 - IL_00ed: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00f2: pop - IL_00f3: ldc.i4.1 - IL_00f4: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.FromResult(int)"" - IL_00f9: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_00fe: stloc.3 - IL_00ff: ldloca.s V_3 - IL_0101: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0106: brtrue.s IL_014b - IL_0108: ldarg.0 - IL_0109: ldc.i4.0 - IL_010a: dup - IL_010b: stloc.0 - IL_010c: stfld ""int C.d__0.<>1__state"" - IL_0111: ldarg.0 - IL_0112: ldloc.3 - IL_0113: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_0118: ldarg.0 - IL_0119: stloc.2 - IL_011a: ldarg.0 - IL_011b: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_0120: ldloca.s V_3 - IL_0122: ldloca.s V_2 - IL_0124: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted, C.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_0129: nop - IL_012a: leave IL_01be - IL_012f: ldarg.0 - IL_0130: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_0135: stloc.3 - IL_0136: ldarg.0 - IL_0137: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_013c: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0142: ldarg.0 - IL_0143: ldc.i4.m1 - IL_0144: dup - IL_0145: stloc.0 - IL_0146: stfld ""int C.d__0.<>1__state"" - IL_014b: ldloca.s V_3 - IL_014d: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0152: pop - IL_0153: call ""void C.End()"" - IL_0158: nop - IL_0159: leave.s IL_0188 - } - catch System.Exception - { - IL_015b: stloc.s V_4 - IL_015d: ldarg.0 - IL_015e: ldc.i4.s -2 - IL_0160: stfld ""int C.d__0.<>1__state"" - IL_0165: ldarg.0 - IL_0166: ldc.i4.0 - IL_0167: stfld ""int C.d__0.<>2__current"" - IL_016c: ldarg.0 - IL_016d: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_0172: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_0177: nop - IL_0178: ldarg.0 - IL_0179: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_017e: ldloc.s V_4 - IL_0180: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_0185: nop - IL_0186: leave.s IL_01be - } - IL_0188: ldarg.0 - IL_0189: ldc.i4.s -2 - IL_018b: stfld ""int C.d__0.<>1__state"" - IL_0190: ldarg.0 - IL_0191: ldc.i4.0 - IL_0192: stfld ""int C.d__0.<>2__current"" - IL_0197: ldarg.0 - IL_0198: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_019d: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_01a2: nop - IL_01a3: ldarg.0 - IL_01a4: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_01a9: ldc.i4.0 - IL_01aa: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_01af: nop - IL_01b0: ret - IL_01b1: ldarg.0 - IL_01b2: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_01b7: ldc.i4.1 - IL_01b8: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_01bd: nop - IL_01be: ret -}"); - diff3.VerifyIL("C.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext", @" + // Verify delta metadata contains expected rows. + using (var md1 = diff1.GetMetadata()) + { + // 1 field def added & 3 methods updated + CheckEncLogDefinitions(md1.Reader, + Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default), + Row(3, TableIndex.TypeDef, EditAndContinueOperation.AddField), + Row(7, TableIndex.Field, EditAndContinueOperation.Default), + Row(1, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default), + Row(1, TableIndex.CustomAttribute, EditAndContinueOperation.Default), + Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default)); + + diff1.VerifyIL("C.d__0.System.Collections.IEnumerator.MoveNext", @" { - // Code size 339 (0x153) - .maxstack 3 - .locals init (int V_0, - System.Runtime.CompilerServices.TaskAwaiter V_1, - C.d__0 V_2, - System.Exception V_3) + // Code size 161 (0xa1) + .maxstack 5 + .locals init (int V_0) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__0.<>1__state"" IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: ldc.i4.s -5 - IL_000a: beq.s IL_001a - IL_000c: br.s IL_000e - IL_000e: ldloc.0 - IL_000f: ldc.i4.s -3 - IL_0011: beq.s IL_001c - IL_0013: br.s IL_0015 - IL_0015: ldloc.0 - IL_0016: brfalse.s IL_001e - IL_0018: br.s IL_0023 - IL_001a: br.s IL_0073 - IL_001c: br.s IL_0042 - IL_001e: br IL_00c5 - - IL_0023: ldloc.0 - IL_0024: ldc.i4.0 - IL_0025: blt.s IL_0032 - IL_0027: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedAsyncMethod + @""" - IL_002c: newobj ""System.InvalidOperationException..ctor(string)"" - IL_0031: throw - - IL_0032: ldloc.0 - IL_0033: ldc.i4.s -4 - IL_0035: bgt.s IL_0042 - IL_0037: ldstr """ + CodeAnalysisResources.EncCannotResumeSuspendedIteratorMethod + @""" - IL_003c: newobj ""System.InvalidOperationException..ctor(string)"" - IL_0041: throw - - IL_0042: ldarg.0 - IL_0043: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0048: brfalse.s IL_004f - IL_004a: leave IL_011c - - IL_004f: ldarg.0 - IL_0050: ldc.i4.m1 - IL_0051: dup - IL_0052: stloc.0 - IL_0053: stfld ""int C.d__0.<>1__state"" - IL_0058: nop - IL_0059: ldarg.0 - IL_005a: call ""int C.F2()"" - IL_005f: stfld ""int C.d__0.<>2__current"" - IL_0064: ldarg.0 - IL_0065: ldc.i4.s -5 - IL_0067: dup - IL_0068: stloc.0 - IL_0069: stfld ""int C.d__0.<>1__state"" - IL_006e: leave IL_0145 - - IL_0073: ldarg.0 - IL_0074: ldc.i4.m1 - IL_0075: dup - IL_0076: stloc.0 - IL_0077: stfld ""int C.d__0.<>1__state"" - IL_007c: ldarg.0 - IL_007d: ldfld ""bool C.d__0.<>w__disposeMode"" - IL_0082: brfalse.s IL_0089 - IL_0084: leave IL_011c - - IL_0089: ldc.i4.1 - IL_008a: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.FromResult(int)"" - IL_008f: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0094: stloc.1 - IL_0095: ldloca.s V_1 - IL_0097: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_009c: brtrue.s IL_00e1 - - IL_009e: ldarg.0 - IL_009f: ldc.i4.0 - IL_00a0: dup - IL_00a1: stloc.0 - IL_00a2: stfld ""int C.d__0.<>1__state"" - IL_00a7: ldarg.0 - IL_00a8: ldloc.1 - IL_00a9: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00ae: ldarg.0 - IL_00af: stloc.2 - IL_00b0: ldarg.0 - IL_00b1: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_00b6: ldloca.s V_1 - IL_00b8: ldloca.s V_2 - IL_00ba: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted, C.d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__0)"" - IL_00bf: nop - IL_00c0: leave IL_0152 - - IL_00c5: ldarg.0 - IL_00c6: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00cb: stloc.1 - IL_00cc: ldarg.0 - IL_00cd: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__0.<>u__1"" - IL_00d2: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_00d8: ldarg.0 - IL_00d9: ldc.i4.m1 - IL_00da: dup - IL_00db: stloc.0 - IL_00dc: stfld ""int C.d__0.<>1__state"" - - IL_00e1: ldloca.s V_1 - IL_00e3: call ""int System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_00e8: pop - IL_00e9: call ""void C.End()"" - IL_00ee: nop - IL_00ef: leave.s IL_011c - } - catch System.Exception - { - IL_00f1: stloc.3 - IL_00f2: ldarg.0 - IL_00f3: ldc.i4.s -2 - IL_00f5: stfld ""int C.d__0.<>1__state"" - IL_00fa: ldarg.0 - IL_00fb: ldc.i4.0 - IL_00fc: stfld ""int C.d__0.<>2__current"" - IL_0101: ldarg.0 - IL_0102: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_0107: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_010c: nop - IL_010d: ldarg.0 - IL_010e: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_0113: ldloc.3 - IL_0114: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetException(System.Exception)"" - IL_0119: nop - IL_011a: leave.s IL_0152 - } - IL_011c: ldarg.0 - IL_011d: ldc.i4.s -2 - IL_011f: stfld ""int C.d__0.<>1__state"" - IL_0124: ldarg.0 - IL_0125: ldc.i4.0 - IL_0126: stfld ""int C.d__0.<>2__current"" - IL_012b: ldarg.0 - IL_012c: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.d__0.<>t__builder"" - IL_0131: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()"" - IL_0136: nop - IL_0137: ldarg.0 - IL_0138: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_013d: ldc.i4.0 - IL_013e: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0143: nop - IL_0144: ret - - IL_0145: ldarg.0 - IL_0146: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore C.d__0.<>v__promiseOfValueOrEnd"" - IL_014b: ldc.i4.1 - IL_014c: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore.SetResult(bool)"" - IL_0151: nop - IL_0152: ret + IL_0007: ldloc.0 + IL_0008: brfalse.s IL_0012 + IL_000a: br.s IL_000c + IL_000c: ldloc.0 + IL_000d: ldc.i4.1 + IL_000e: beq.s IL_0014 + IL_0010: br.s IL_0016 + IL_0012: br.s IL_0018 + IL_0014: br.s IL_006b + IL_0016: ldc.i4.0 + IL_0017: ret + IL_0018: ldarg.0 + IL_0019: ldc.i4.m1 + IL_001a: stfld ""int C.d__0.<>1__state"" + IL_001f: nop + IL_0020: nop + IL_0021: ldarg.0 + IL_0022: ldc.i4.1 + IL_0023: newarr ""double"" + IL_0028: dup + IL_0029: ldc.i4.0 + IL_002a: ldc.r8 1 + IL_0033: stelem.r8 + IL_0034: stfld ""double[] C.d__0.<>s__4"" + IL_0039: ldarg.0 + IL_003a: ldc.i4.0 + IL_003b: stfld ""int C.d__0.<>s__2"" + IL_0040: br.s IL_0088 + IL_0042: ldarg.0 + IL_0043: ldarg.0 + IL_0044: ldfld ""double[] C.d__0.<>s__4"" + IL_0049: ldarg.0 + IL_004a: ldfld ""int C.d__0.<>s__2"" + IL_004f: ldelem.r8 + IL_0050: box ""double"" + IL_0055: stfld ""object C.d__0.5__3"" + IL_005a: nop + IL_005b: ldarg.0 + IL_005c: ldc.i4.1 + IL_005d: stfld ""int C.d__0.<>2__current"" + IL_0062: ldarg.0 + IL_0063: ldc.i4.1 + IL_0064: stfld ""int C.d__0.<>1__state"" + IL_0069: ldc.i4.1 + IL_006a: ret + IL_006b: ldarg.0 + IL_006c: ldc.i4.m1 + IL_006d: stfld ""int C.d__0.<>1__state"" + IL_0072: nop + IL_0073: ldarg.0 + IL_0074: ldnull + IL_0075: stfld ""object C.d__0.5__3"" + IL_007a: ldarg.0 + IL_007b: ldarg.0 + IL_007c: ldfld ""int C.d__0.<>s__2"" + IL_0081: ldc.i4.1 + IL_0082: add + IL_0083: stfld ""int C.d__0.<>s__2"" + IL_0088: ldarg.0 + IL_0089: ldfld ""int C.d__0.<>s__2"" + IL_008e: ldarg.0 + IL_008f: ldfld ""double[] C.d__0.<>s__4"" + IL_0094: ldlen + IL_0095: conv.i4 + IL_0096: blt.s IL_0042 + IL_0098: ldarg.0 + IL_0099: ldnull + IL_009a: stfld ""double[] C.d__0.<>s__4"" + IL_009f: ldc.i4.0 + IL_00a0: ret }"); + } + } } [Fact] public void HoistedVariables_MultipleGenerations() { - var source0 = MarkedSource(@" + var source0 = @" using System.Threading.Tasks; class C { static async Task F() // testing type changes G0 -> G1, G1 -> G2 { - bool a1 = true; - int a2 = 3; - await Task.Delay(0); + bool a1 = true; + int a2 = 3; + await Task.Delay(0); return 1; } static async Task G() // testing G1 -> G3 { - C c = new C(); - bool a1 = true; - await Task.Delay(0); + C c = new C(); + bool a1 = true; + await Task.Delay(0); return 1; } static async Task H() // testing G0 -> G3 { - C c = new C(); - bool a1 = true; - await Task.Delay(0); + C c = new C(); + bool a1 = true; + await Task.Delay(0); return 1; } -}"); - var source1 = MarkedSource(@" +}"; + var source1 = @" using System.Threading.Tasks; class C { static async Task F() // updated { - C a1 = new C(); - int a2 = 3; - await Task.Delay(0); + C a1 = new C(); + int a2 = 3; + await Task.Delay(0); return 1; } static async Task G() // updated { - C c = new C(); - bool a1 = true; - await Task.Delay(0); + C c = new C(); + bool a1 = true; + await Task.Delay(0); return 2; } static async Task H() { - C c = new C(); - bool a1 = true; - await Task.Delay(0); + C c = new C(); + bool a1 = true; + await Task.Delay(0); return 1; } -}"); - var source2 = MarkedSource(@" +}"; + var source2 = @" using System.Threading.Tasks; class C { static async Task F() // updated { - bool a1 = true; - C a2 = new C(); - await Task.Delay(0); + bool a1 = true; + C a2 = new C(); + await Task.Delay(0); return 1; } static async Task G() { - C c = new C(); - bool a1 = true; - await Task.Delay(0); + C c = new C(); + bool a1 = true; + await Task.Delay(0); return 2; } static async Task H() { - C c = new C(); - bool a1 = true; - await Task.Delay(0); + C c = new C(); + bool a1 = true; + await Task.Delay(0); return 1; } -}"); - var source3 = MarkedSource(@" +}"; + var source3 = @" using System.Threading.Tasks; class C { static async Task F() { - bool a1 = true; - C a2 = new C(); - await Task.Delay(0); + bool a1 = true; + C a2 = new C(); + await Task.Delay(0); return 1; } static async Task G() // updated { - C c = new C(); - C a1 = new C(); - await Task.Delay(0); + C c = new C(); + C a1 = new C(); + await Task.Delay(0); return 1; } static async Task H() // updated { - C c = new C(); - C a1 = new C(); - await Task.Delay(0); + C c = new C(); + C a1 = new C(); + await Task.Delay(0); return 1; } -}"); +}"; // Rude edit but the compiler should handle it. - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); - var compilation1 = compilation0.WithSource(source1.Tree); - var compilation2 = compilation1.WithSource(source2.Tree); - var compilation3 = compilation2.WithSource(source3.Tree); + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All)); + var compilation1 = compilation0.WithSource(source1); + var compilation2 = compilation1.WithSource(source2); + var compilation3 = compilation2.WithSource(source3); var f0 = compilation0.GetMember("C.F"); var f1 = compilation1.GetMember("C.F"); @@ -6132,36 +1837,34 @@ static async Task H() // updated }); var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); - var syntaxMap1 = GetSyntaxMapFromMarkers(source0, source1); + var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, syntaxMap1, preserveLocalVariables: true), - SemanticEdit.Create(SemanticEditKind.Update, g0, g1, syntaxMap1, preserveLocalVariables: true))); + SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetEquivalentNodesMap(f1, f0), preserveLocalVariables: true), + SemanticEdit.Create(SemanticEditKind.Update, g0, g1, GetEquivalentNodesMap(g1, g0), preserveLocalVariables: true))); diff1.VerifySynthesizedMembers( "C: {d__0, d__1}", "C.d__0: {<>1__state, <>t__builder, 5__3, 5__2, <>u__1, MoveNext, SetStateMachine}", "C.d__1: {<>1__state, <>t__builder, 5__1, 5__2, <>u__1, MoveNext, SetStateMachine}"); - var syntaxMap2 = GetSyntaxMapFromMarkers(source1, source2); var diff2 = compilation2.EmitDifference( diff1.NextGeneration, ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f1, f2, syntaxMap2, preserveLocalVariables: true))); + SemanticEdit.Create(SemanticEditKind.Update, f1, f2, GetEquivalentNodesMap(f2, f1), preserveLocalVariables: true))); diff2.VerifySynthesizedMembers( "C: {d__0, d__1}", "C.d__0: {<>1__state, <>t__builder, 5__4, 5__5, <>u__1, MoveNext, SetStateMachine, 5__3, 5__2}", "C.d__1: {<>1__state, <>t__builder, 5__1, 5__2, <>u__1, MoveNext, SetStateMachine}"); - var syntaxMap3 = GetSyntaxMapFromMarkers(source2, source3); var diff3 = compilation3.EmitDifference( diff2.NextGeneration, ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, g2, g3, syntaxMap3, preserveLocalVariables: true), - SemanticEdit.Create(SemanticEditKind.Update, h2, h3, syntaxMap3, preserveLocalVariables: true))); + SemanticEdit.Create(SemanticEditKind.Update, g2, g3, GetEquivalentNodesMap(g3, g2), preserveLocalVariables: true), + SemanticEdit.Create(SemanticEditKind.Update, h2, h3, GetEquivalentNodesMap(h3, h2), preserveLocalVariables: true))); diff3.VerifySynthesizedMembers( "C: {d__1, d__2, d__0}", @@ -6428,7 +2131,7 @@ class C public IEnumerable F() { dynamic x = 1; - yield return 1; + yield return 1; Console.WriteLine((int)x + <>); } } @@ -6735,7 +2438,7 @@ static async Task G() [MemberData(nameof(ExternalPdbFormats))] public void Awaiters_MultipleGenerations(DebugInformationFormat format) { - var source0 = MarkedSource(@" + var source0 = @" using System.Threading.Tasks; class C @@ -6746,24 +2449,24 @@ class C static async Task F() // testing type changes G0 -> G1, G1 -> G2 { - await A1(); - await A2(); + await A1(); + await A2(); return 1; } static async Task G() // testing G1 -> G3 { - await A1(); + await A1(); return 1; } static async Task H() // testing G0 -> G3 { - await A1(); + await A1(); return 1; } -}"); - var source1 = MarkedSource(@" +}"; + var source1 = @" using System.Threading.Tasks; class C @@ -6774,24 +2477,24 @@ class C static async Task F() // updated { - await A3(); - await A2(); + await A3(); + await A2(); return 1; } static async Task G() // updated { - await A1(); + await A1(); return 2; } static async Task H() { - await A1(); + await A1(); return 1; } -}"); - var source2 = MarkedSource(@" +}"; + var source2 = @" using System.Threading.Tasks; class C @@ -6802,24 +2505,24 @@ class C static async Task F() // updated { - await A1(); - await A3(); + await A1(); + await A3(); return 1; } static async Task G() { - await A1(); + await A1(); return 2; } static async Task H() { - await A1(); + await A1(); return 1; } -}"); - var source3 = MarkedSource(@" +}"; + var source3 = @" using System.Threading.Tasks; class C @@ -6830,30 +2533,30 @@ class C static async Task F() { - await A1(); - await A3(); + await A1(); + await A3(); return 1; } static async Task G() // updated { - await A3(); + await A3(); return 1; } static async Task H() // updated { - await A3(); + await A3(); return 1; } -}"); +}"; // Rude edit but the compiler should handle it. - var compilation0 = CreateCompilationWithMscorlib45(source0.Tree, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All), assemblyName: "A"); - var compilation1 = compilation0.WithSource(source1.Tree); - var compilation2 = compilation1.WithSource(source2.Tree); - var compilation3 = compilation2.WithSource(source3.Tree); + var compilation0 = CreateCompilationWithMscorlib45(source0, options: ComSafeDebugDll.WithMetadataImportOptions(MetadataImportOptions.All), assemblyName: "A"); + var compilation1 = compilation0.WithSource(source1); + var compilation2 = compilation1.WithSource(source2); + var compilation3 = compilation2.WithSource(source3); var f0 = compilation0.GetMember("C.F"); var f1 = compilation1.GetMember("C.F"); @@ -6884,35 +2587,32 @@ static async Task H() // updated var md0 = ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData); var generation0 = EmitBaseline.CreateInitialBaseline(md0, v0.CreateSymReader().GetEncMethodDebugInfo); - var syntaxMap1 = GetSyntaxMapFromMarkers(source0, source1); var diff1 = compilation1.EmitDifference( generation0, ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f0, f1, syntaxMap1, preserveLocalVariables: true), - SemanticEdit.Create(SemanticEditKind.Update, g0, g1, syntaxMap1, preserveLocalVariables: true))); + SemanticEdit.Create(SemanticEditKind.Update, f0, f1, GetSyntaxMapByKind(f0, SyntaxKind.Block), preserveLocalVariables: true), + SemanticEdit.Create(SemanticEditKind.Update, g0, g1, GetSyntaxMapByKind(g0, SyntaxKind.Block), preserveLocalVariables: true))); diff1.VerifySynthesizedMembers( "C: {d__3, d__4}", "C.d__3: {<>1__state, <>t__builder, <>u__3, <>u__2, MoveNext, SetStateMachine}", "C.d__4: {<>1__state, <>t__builder, <>u__1, MoveNext, SetStateMachine}"); - var syntaxMap2 = GetSyntaxMapFromMarkers(source1, source2); var diff2 = compilation2.EmitDifference( diff1.NextGeneration, ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, f1, f2, syntaxMap2, preserveLocalVariables: true))); + SemanticEdit.Create(SemanticEditKind.Update, f1, f2, GetSyntaxMapByKind(f1, SyntaxKind.Block), preserveLocalVariables: true))); diff2.VerifySynthesizedMembers( "C: {d__3, d__4}", "C.d__3: {<>1__state, <>t__builder, <>u__4, <>u__3, MoveNext, SetStateMachine, <>u__2}", "C.d__4: {<>1__state, <>t__builder, <>u__1, MoveNext, SetStateMachine}"); - var syntaxMap3 = GetSyntaxMapFromMarkers(source2, source3); var diff3 = compilation3.EmitDifference( diff2.NextGeneration, ImmutableArray.Create( - SemanticEdit.Create(SemanticEditKind.Update, g2, g3, syntaxMap3, preserveLocalVariables: true), - SemanticEdit.Create(SemanticEditKind.Update, h2, h3, syntaxMap3, preserveLocalVariables: true))); + SemanticEdit.Create(SemanticEditKind.Update, g2, g3, GetSyntaxMapByKind(g2, SyntaxKind.Block), preserveLocalVariables: true), + SemanticEdit.Create(SemanticEditKind.Update, h2, h3, GetSyntaxMapByKind(h2, SyntaxKind.Block), preserveLocalVariables: true))); diff3.VerifySynthesizedMembers( "C: {d__4, d__5, d__3}", @@ -6941,9 +2641,9 @@ static async Task H() // updated public abstract bool TryGetPreviousLambda(SyntaxNode lambdaOrLambdaBodySyntax, bool isLambdaBody, out DebugId lambdaId); - - /// - /// State number to be used for next state of the state machine, - /// or if none of the previous versions of the method was a state machine with a increasing state - /// - /// True if the state number increases with progress, false if it decreases. - public abstract int? GetFirstUnusedStateMachineState(bool increasing); - - /// - /// For a given node associated with entering a state of a state machine in the new compilation, - /// returns the ordinal of the corresponding state in the previous version of the state machine. - /// - /// - /// True if there is a corresponding node in the previous code version that matches the given . - /// - /// - /// is an await expression, yield return statement, or try block syntax node. - /// - public abstract bool TryGetPreviousStateMachineState(SyntaxNode syntax, out int stateOrdinal); } } diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinue/AddedOrChangedMethodInfo.cs b/src/Compilers/Core/Portable/Emit/EditAndContinue/AddedOrChangedMethodInfo.cs index 98080deeaa1c7..2f98ba9d78668 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinue/AddedOrChangedMethodInfo.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinue/AddedOrChangedMethodInfo.cs @@ -24,7 +24,6 @@ internal readonly struct AddedOrChangedMethodInfo public readonly string? StateMachineTypeName; public readonly ImmutableArray StateMachineHoistedLocalSlotsOpt; public readonly ImmutableArray StateMachineAwaiterSlotsOpt; - public readonly StateMachineStatesDebugInfo StateMachineStates; public AddedOrChangedMethodInfo( DebugId methodId, @@ -33,18 +32,17 @@ public AddedOrChangedMethodInfo( ImmutableArray closureDebugInfo, string? stateMachineTypeName, ImmutableArray stateMachineHoistedLocalSlotsOpt, - ImmutableArray stateMachineAwaiterSlotsOpt, - StateMachineStatesDebugInfo stateMachineStates) + ImmutableArray stateMachineAwaiterSlotsOpt) { // An updated method will carry its id over, // an added method id has generation set to the current generation ordinal. Debug.Assert(methodId.Generation >= 0); // each state machine has to have awaiters: - Debug.Assert(stateMachineAwaiterSlotsOpt.IsDefault == stateMachineTypeName is null); + Debug.Assert(stateMachineAwaiterSlotsOpt.IsDefault == (stateMachineTypeName == null)); // a state machine might not have hoisted variables: - Debug.Assert(stateMachineHoistedLocalSlotsOpt.IsDefault || stateMachineTypeName is not null); + Debug.Assert(stateMachineHoistedLocalSlotsOpt.IsDefault || (stateMachineTypeName != null)); MethodId = methodId; Locals = locals; @@ -53,7 +51,6 @@ public AddedOrChangedMethodInfo( StateMachineTypeName = stateMachineTypeName; StateMachineHoistedLocalSlotsOpt = stateMachineHoistedLocalSlotsOpt; StateMachineAwaiterSlotsOpt = stateMachineAwaiterSlotsOpt; - StateMachineStates = stateMachineStates; } public AddedOrChangedMethodInfo MapTypes(SymbolMatcher map) @@ -66,7 +63,7 @@ public AddedOrChangedMethodInfo MapTypes(SymbolMatcher map) var mappedAwaiterSlots = StateMachineAwaiterSlotsOpt.IsDefault ? default : ImmutableArray.CreateRange(StateMachineAwaiterSlotsOpt, static (typeRef, map) => (typeRef is null) ? null : map.MapReference(typeRef), map); - return new AddedOrChangedMethodInfo(MethodId, mappedLocals, LambdaDebugInfo, ClosureDebugInfo, StateMachineTypeName, mappedHoistedLocalSlots, mappedAwaiterSlots, StateMachineStates); + return new AddedOrChangedMethodInfo(MethodId, mappedLocals, LambdaDebugInfo, ClosureDebugInfo, StateMachineTypeName, mappedHoistedLocalSlots, mappedAwaiterSlots); } private static EncLocalInfo MapLocalInfo(EncLocalInfo info, SymbolMatcher map) diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinue/DefinitionMap.cs b/src/Compilers/Core/Portable/Emit/EditAndContinue/DefinitionMap.cs index 5eb02ef5dfe3c..d5dca8be2c661 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinue/DefinitionMap.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinue/DefinitionMap.cs @@ -143,7 +143,7 @@ protected abstract void GetStateMachineFieldMapFromMetadata( out int awaiterSlotCount); protected abstract ImmutableArray GetLocalSlotMapFromMetadata(StandaloneSignatureHandle handle, EditAndContinueMethodDebugInformation debugInfo); - protected abstract ITypeSymbolInternal? TryGetStateMachineType(MethodDefinitionHandle methodHandle); + protected abstract ITypeSymbolInternal? TryGetStateMachineType(EntityHandle methodHandle); internal VariableSlotAllocator? TryCreateVariableSlotAllocator(EmitBaseline baseline, Compilation compilation, IMethodSymbolInternal method, IMethodSymbolInternal topLevelMethod, DiagnosticBag diagnostics) { @@ -167,9 +167,6 @@ protected abstract void GetStateMachineFieldMapFromMetadata( IReadOnlyDictionary? awaiterMap = null; IReadOnlyDictionary>? lambdaMap = null; IReadOnlyDictionary? closureMap = null; - IReadOnlyDictionary? stateMachineStateMap = null; - int? firstUnusedIncreasingStateMachineState = null; - int? firstUnusedDecreasingStateMachineState = null; int hoistedLocalSlotCount = 0; int awaiterSlotCount = 0; @@ -185,10 +182,6 @@ protected abstract void GetStateMachineFieldMapFromMetadata( methodId = addedOrChangedMethod.MethodId; MakeLambdaAndClosureMaps(addedOrChangedMethod.LambdaDebugInfo, addedOrChangedMethod.ClosureDebugInfo, out lambdaMap, out closureMap); - MakeStateMachineStateMap(addedOrChangedMethod.StateMachineStates.States, out stateMachineStateMap); - - firstUnusedIncreasingStateMachineState = addedOrChangedMethod.StateMachineStates.FirstUnusedIncreasingStateMachineState; - firstUnusedDecreasingStateMachineState = addedOrChangedMethod.StateMachineStates.FirstUnusedDecreasingStateMachineState; if (addedOrChangedMethod.StateMachineTypeName != null) { @@ -248,14 +241,6 @@ protected abstract void GetStateMachineFieldMapFromMetadata( MakeLambdaAndClosureMaps(debugInfo.Lambdas, debugInfo.Closures, out lambdaMap, out closureMap); } - MakeStateMachineStateMap(debugInfo.StateMachineStates, out stateMachineStateMap); - - if (!debugInfo.StateMachineStates.IsDefaultOrEmpty) - { - firstUnusedIncreasingStateMachineState = debugInfo.StateMachineStates.Max(s => s.StateNumber) + 1; - firstUnusedDecreasingStateMachineState = debugInfo.StateMachineStates.Min(s => s.StateNumber) - 1; - } - ITypeSymbolInternal? stateMachineType = TryGetStateMachineType(previousHandle); if (stateMachineType != null) { @@ -332,9 +317,6 @@ protected abstract void GetStateMachineFieldMapFromMetadata( hoistedLocalMap, awaiterSlotCount, awaiterMap, - stateMachineStateMap, - firstUnusedIncreasingStateMachineState, - firstUnusedDecreasingStateMachineState, GetLambdaSyntaxFacts()); } @@ -374,15 +356,6 @@ private static void MakeLambdaAndClosureMaps( closureMap = closures; } - private static void MakeStateMachineStateMap( - ImmutableArray debugInfos, - out IReadOnlyDictionary? map) - { - map = debugInfos.IsDefault ? - null : - debugInfos.ToDictionary(entry => entry.SyntaxOffset, entry => entry.StateNumber); - } - private static void GetStateMachineFieldMapFromPreviousCompilation( ImmutableArray hoistedLocalSlots, ImmutableArray hoistedAwaiters, diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs b/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs index 42c215222b11f..4412a2bbbe4bf 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinue/DeltaMetadataWriter.cs @@ -759,8 +759,7 @@ protected override StandaloneSignatureHandle SerializeLocalVariablesSignature(IM body.ClosureDebugInfo, body.StateMachineTypeName, body.StateMachineHoistedLocalSlots, - body.StateMachineAwaiterSlots, - body.StateMachineStatesDebugInfo); + body.StateMachineAwaiterSlots); _addedOrChangedMethods.Add(body.MethodDefinition, info); diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinue/EncVariableSlotAllocator.cs b/src/Compilers/Core/Portable/Emit/EditAndContinue/EncVariableSlotAllocator.cs index 841bd83956ca3..6bc4ceff225b0 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinue/EncVariableSlotAllocator.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinue/EncVariableSlotAllocator.cs @@ -35,9 +35,6 @@ internal sealed class EncVariableSlotAllocator : VariableSlotAllocator private readonly IReadOnlyDictionary? _hoistedLocalSlots; private readonly int _awaiterCount; private readonly IReadOnlyDictionary? _awaiterMap; - private readonly IReadOnlyDictionary? _stateMachineStateMap; // SyntaxOffset -> State Ordinal - private readonly int? _firstUnusedDecreasingStateMachineState; - private readonly int? _firstUnusedIncreasingStateMachineState; // closures: private readonly IReadOnlyDictionary>? _lambdaMap; // SyntaxOffset -> (Lambda Id, Closure Ordinal) @@ -58,9 +55,6 @@ public EncVariableSlotAllocator( IReadOnlyDictionary? hoistedLocalSlots, int awaiterCount, IReadOnlyDictionary? awaiterMap, - IReadOnlyDictionary? stateMachineStateMap, - int? firstUnusedIncreasingStateMachineState, - int? firstUnusedDecreasingStateMachineState, LambdaSyntaxFacts lambdaSyntaxFacts) { Debug.Assert(!previousLocals.IsDefault); @@ -75,12 +69,9 @@ public EncVariableSlotAllocator( _stateMachineTypeName = stateMachineTypeName; _awaiterCount = awaiterCount; _awaiterMap = awaiterMap; - _stateMachineStateMap = stateMachineStateMap; _lambdaMap = lambdaMap; _closureMap = closureMap; _lambdaSyntaxFacts = lambdaSyntaxFacts; - _firstUnusedIncreasingStateMachineState = firstUnusedIncreasingStateMachineState; - _firstUnusedDecreasingStateMachineState = firstUnusedDecreasingStateMachineState; // Create a map from local info to slot. var previousLocalInfoToSlot = new Dictionary(); @@ -328,21 +319,5 @@ public override bool TryGetPreviousLambda(SyntaxNode lambdaOrLambdaBodySyntax, b lambdaId = default; return false; } - - public override int? GetFirstUnusedStateMachineState(bool increasing) - => increasing ? _firstUnusedIncreasingStateMachineState : _firstUnusedDecreasingStateMachineState; - - public override bool TryGetPreviousStateMachineState(SyntaxNode syntax, out int stateOrdinal) - { - if (_stateMachineStateMap != null && - TryGetPreviousSyntaxOffset(syntax, out int syntaxOffset) && - _stateMachineStateMap.TryGetValue(syntaxOffset, out stateOrdinal)) - { - return true; - } - - stateOrdinal = -1; - return false; - } } } diff --git a/src/Compilers/Core/Portable/Emit/EditAndContinueMethodDebugInformation.cs b/src/Compilers/Core/Portable/Emit/EditAndContinueMethodDebugInformation.cs index 4cc95b0b8b427..c15f3a874c9b2 100644 --- a/src/Compilers/Core/Portable/Emit/EditAndContinueMethodDebugInformation.cs +++ b/src/Compilers/Core/Portable/Emit/EditAndContinueMethodDebugInformation.cs @@ -22,14 +22,8 @@ public readonly struct EditAndContinueMethodDebugInformation internal readonly ImmutableArray LocalSlots; internal readonly ImmutableArray Lambdas; internal readonly ImmutableArray Closures; - internal readonly ImmutableArray StateMachineStates; - - internal EditAndContinueMethodDebugInformation( - int methodOrdinal, - ImmutableArray localSlots, - ImmutableArray closures, - ImmutableArray lambdas, - ImmutableArray stateMachineStates) + + internal EditAndContinueMethodDebugInformation(int methodOrdinal, ImmutableArray localSlots, ImmutableArray closures, ImmutableArray lambdas) { Debug.Assert(methodOrdinal >= -1); @@ -37,7 +31,6 @@ internal EditAndContinueMethodDebugInformation( LocalSlots = localSlots; Lambdas = lambdas; Closures = closures; - StateMachineStates = stateMachineStates; } /// @@ -47,25 +40,9 @@ internal EditAndContinueMethodDebugInformation( /// Lambda and closure map. /// Invalid data. public static EditAndContinueMethodDebugInformation Create(ImmutableArray compressedSlotMap, ImmutableArray compressedLambdaMap) - => Create(compressedSlotMap, compressedLambdaMap, compressedStateMachineStateMap: default); - - - /// - /// Deserializes Edit and Continue method debug information from specified blobs. - /// - /// Local variable slot map. - /// Lambda and closure map. - /// State machine suspension points, if the method is the MoveNext method of the state machine. - /// Invalid data. - public static EditAndContinueMethodDebugInformation Create(ImmutableArray compressedSlotMap, ImmutableArray compressedLambdaMap, ImmutableArray compressedStateMachineStateMap) { UncompressLambdaMap(compressedLambdaMap, out var methodOrdinal, out var closures, out var lambdas); - return new EditAndContinueMethodDebugInformation( - methodOrdinal, - UncompressSlotMap(compressedSlotMap), - closures, - lambdas, - UncompressStateMachineStates(compressedStateMachineStateMap)); + return new EditAndContinueMethodDebugInformation(methodOrdinal, UncompressSlotMap(compressedSlotMap), closures, lambdas); } private static InvalidDataException CreateInvalidDataException(ImmutableArray data, int offset) @@ -300,56 +277,5 @@ internal void SerializeLambdaMap(BlobBuilder writer) } #endregion - - #region State Machine States - - /// Invalid data. - private static unsafe ImmutableArray UncompressStateMachineStates(ImmutableArray compressedStateMachineStates) - { - if (compressedStateMachineStates.IsDefaultOrEmpty) - { - return default; - } - - var mapBuilder = ArrayBuilder.GetInstance(); - - fixed (byte* ptr = &compressedStateMachineStates.ToArray()[0]) - { - var blobReader = new BlobReader(ptr, compressedStateMachineStates.Length); - - try - { - int count = blobReader.ReadCompressedInteger(); - - while (count > 0) - { - int stateNumber = blobReader.ReadCompressedSignedInteger(); - int syntaxOffset = blobReader.ReadCompressedInteger(); - - mapBuilder.Add(new StateMachineStateDebugInfo(syntaxOffset, stateNumber)); - count--; - } - } - catch (BadImageFormatException) - { - throw CreateInvalidDataException(compressedStateMachineStates, blobReader.Offset); - } - } - - return mapBuilder.ToImmutableAndFree(); - } - - internal void SerializeStateMachineStates(BlobBuilder writer) - { - writer.WriteCompressedInteger(StateMachineStates.Length); - - foreach (StateMachineStateDebugInfo state in StateMachineStates) - { - writer.WriteCompressedSignedInteger(state.StateNumber); - writer.WriteCompressedInteger(state.SyntaxOffset); - } - } - - #endregion } } diff --git a/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedMethod.cs b/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedMethod.cs index 6d8771f789e6f..66692ffdf4ed3 100644 --- a/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedMethod.cs +++ b/src/Compilers/Core/Portable/Emit/NoPia/CommonEmbeddedMethod.cs @@ -161,9 +161,6 @@ public EmptyBody(CommonEmbeddedMethod method) ImmutableArray Cci.IMethodBody.LambdaDebugInfo => default(ImmutableArray); - public StateMachineStatesDebugInfo StateMachineStatesDebugInfo - => default; - public DebugId MethodId => default(DebugId); } diff --git a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs index 077e195f7fdd8..16c3a5db53233 100644 --- a/src/Compilers/Core/Portable/MetadataReader/PEModule.cs +++ b/src/Compilers/Core/Portable/MetadataReader/PEModule.cs @@ -1780,11 +1780,6 @@ private bool TryExtractValueFromAttribute(CustomAttributeHandle handle, out T } #nullable disable - internal bool HasStateMachineAttribute(MethodDefinitionHandle handle, out string stateMachineTypeName) - => HasStringValuedAttribute(handle, AttributeDescription.AsyncStateMachineAttribute, out stateMachineTypeName) || - HasStringValuedAttribute(handle, AttributeDescription.IteratorStateMachineAttribute, out stateMachineTypeName) || - HasStringValuedAttribute(handle, AttributeDescription.AsyncIteratorStateMachineAttribute, out stateMachineTypeName); - internal bool HasStringValuedAttribute(EntityHandle token, AttributeDescription description, out string value) { AttributeInfo info = FindTargetAttribute(token, description); diff --git a/src/Compilers/Core/Portable/PEWriter/CustomDebugInfoWriter.cs b/src/Compilers/Core/Portable/PEWriter/CustomDebugInfoWriter.cs index 72fc9d41e1336..2371acc5d48a8 100644 --- a/src/Compilers/Core/Portable/PEWriter/CustomDebugInfoWriter.cs +++ b/src/Compilers/Core/Portable/PEWriter/CustomDebugInfoWriter.cs @@ -147,14 +147,6 @@ internal static void SerializeCustomDebugInformation(ref CustomDebugInfoEncoder debugInfo, (info, builder) => info.SerializeLambdaMap(builder)); } - - if (!debugInfo.StateMachineStates.IsDefaultOrEmpty) - { - encoder.AddRecord( - CustomDebugInfoKind.EditAndContinueStateMachineStateMap, - debugInfo, - (info, builder) => info.SerializeStateMachineStates(builder)); - } } private static ArrayBuilder GetLocalInfoToSerialize( diff --git a/src/Compilers/Core/Portable/PEWriter/Members.cs b/src/Compilers/Core/Portable/PEWriter/Members.cs index 0625117b7b837..fcb78a61af057 100644 --- a/src/Compilers/Core/Portable/PEWriter/Members.cs +++ b/src/Compilers/Core/Portable/PEWriter/Members.cs @@ -475,7 +475,6 @@ ImmutableArray ExceptionRegions ImmutableArray ClosureDebugInfo { get; } ImmutableArray LambdaDebugInfo { get; } - StateMachineStatesDebugInfo StateMachineStatesDebugInfo { get; } DynamicAnalysisMethodBodyData DynamicAnalysisData { get; } } diff --git a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs index 74b080264b787..bfd660f5e4b1f 100644 --- a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs +++ b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.PortablePdb.cs @@ -817,18 +817,6 @@ private void SerializeEncMethodDebugInformation(IMethodBody methodBody, MethodDe kind: _debugMetadataOpt.GetOrAddGuid(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap), value: _debugMetadataOpt.GetOrAddBlob(writer)); } - - if (!encInfo.StateMachineStates.IsDefaultOrEmpty) - { - var writer = new BlobBuilder(); - - encInfo.SerializeStateMachineStates(writer); - - _debugMetadataOpt.AddCustomDebugInformation( - parent: method, - kind: _debugMetadataOpt.GetOrAddGuid(PortableCustomDebugInfoKinds.EncStateMachineStateMap), - value: _debugMetadataOpt.GetOrAddBlob(writer)); - } } #endregion diff --git a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs index e8fd04f5faace..17defcf93881b 100644 --- a/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs +++ b/src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs @@ -4054,12 +4054,7 @@ internal static EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(IMet encLocalSlots = GetLocalSlotDebugInfos(encSlotInfo); } - return new EditAndContinueMethodDebugInformation( - methodBody.MethodId.Ordinal, - encLocalSlots, - methodBody.ClosureDebugInfo, - methodBody.LambdaDebugInfo, - methodBody.StateMachineStatesDebugInfo.States); + return new EditAndContinueMethodDebugInformation(methodBody.MethodId.Ordinal, encLocalSlots, methodBody.ClosureDebugInfo, methodBody.LambdaDebugInfo); } internal static ImmutableArray GetLocalSlotDebugInfos(ImmutableArray locals) diff --git a/src/Compilers/Core/Portable/PEWriter/RootModuleStaticConstructor.cs b/src/Compilers/Core/Portable/PEWriter/RootModuleStaticConstructor.cs index b6001e1a37a07..b397eb48370b9 100644 --- a/src/Compilers/Core/Portable/PEWriter/RootModuleStaticConstructor.cs +++ b/src/Compilers/Core/Portable/PEWriter/RootModuleStaticConstructor.cs @@ -161,11 +161,8 @@ public RootModuleStaticConstructor(ITypeDefinition containingTypeDefinition, Imm public ImmutableArray LambdaDebugInfo => ImmutableArray.Empty; - public StateMachineStatesDebugInfo StateMachineStatesDebugInfo => default; - public DynamicAnalysisMethodBodyData DynamicAnalysisData => null; - public sealed override bool Equals(object obj) { // It is not supported to rely on default equality of these Cci objects, an explicit way to compare and hash them should be used. diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index a28db91aaa246..1d622432a2be9 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -56,7 +56,6 @@ Microsoft.CodeAnalysis.SymbolVisitor Microsoft.CodeAnalysis.SymbolVisitor.SymbolVisitor() -> void override sealed Microsoft.CodeAnalysis.Diagnostic.Equals(object? obj) -> bool *REMOVED*static Microsoft.CodeAnalysis.SyntaxNodeExtensions.ReplaceSyntax(this TRoot! root, System.Collections.Generic.IEnumerable! nodes, System.Func! computeReplacementNode, System.Collections.Generic.IEnumerable! tokens, System.Func! computeReplacementToken, System.Collections.Generic.IEnumerable! trivia, System.Func! computeReplacementTrivia) -> TRoot! -static Microsoft.CodeAnalysis.Emit.EditAndContinueMethodDebugInformation.Create(System.Collections.Immutable.ImmutableArray compressedSlotMap, System.Collections.Immutable.ImmutableArray compressedLambdaMap, System.Collections.Immutable.ImmutableArray compressedStateMachineStateMap) -> Microsoft.CodeAnalysis.Emit.EditAndContinueMethodDebugInformation static Microsoft.CodeAnalysis.SyntaxNodeExtensions.ReplaceSyntax(this TRoot! root, System.Collections.Generic.IEnumerable? nodes, System.Func? computeReplacementNode, System.Collections.Generic.IEnumerable? tokens, System.Func? computeReplacementToken, System.Collections.Generic.IEnumerable? trivia, System.Func? computeReplacementTrivia) -> TRoot! const Microsoft.CodeAnalysis.WellKnownMemberNames.CheckedDecrementOperatorName = "op_CheckedDecrement" -> string! const Microsoft.CodeAnalysis.WellKnownMemberNames.CheckedIncrementOperatorName = "op_CheckedIncrement" -> string! diff --git a/src/Compilers/Core/Portable/WellKnownMember.cs b/src/Compilers/Core/Portable/WellKnownMember.cs index fe2b3e646e0f7..8eef3970f4ebb 100644 --- a/src/Compilers/Core/Portable/WellKnownMember.cs +++ b/src/Compilers/Core/Portable/WellKnownMember.cs @@ -500,7 +500,6 @@ internal enum WellKnownMember System_Runtime_CompilerServices_ITuple__get_Length, System_InvalidOperationException__ctor, - System_InvalidOperationException__ctorString, System_Runtime_CompilerServices_SwitchExpressionException__ctor, System_Runtime_CompilerServices_SwitchExpressionException__ctorObject, diff --git a/src/Compilers/Core/Portable/WellKnownMembers.cs b/src/Compilers/Core/Portable/WellKnownMembers.cs index 1f8f98524758f..d43618ec1631b 100644 --- a/src/Compilers/Core/Portable/WellKnownMembers.cs +++ b/src/Compilers/Core/Portable/WellKnownMembers.cs @@ -3454,14 +3454,6 @@ static WellKnownMembers() 0, // Method Signature (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, - // System_InvalidOperationException__ctorString - (byte)MemberFlags.Constructor, // Flags - (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_InvalidOperationException - WellKnownType.ExtSentinel), // DeclaringTypeId - 0, // Arity - 1, // Method Signature - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_Void, - (byte)SignatureTypeCode.TypeHandle, (byte)SpecialType.System_String, - // System_Runtime_CompilerServices_SwitchExpressionException__ctor (byte)MemberFlags.Constructor, // Flags (byte)WellKnownType.ExtSentinel, (byte)(WellKnownType.System_Runtime_CompilerServices_SwitchExpressionException - WellKnownType.ExtSentinel),// DeclaringTypeId @@ -4065,7 +4057,6 @@ static WellKnownMembers() "get_Item", // System_Runtime_CompilerServices_ITuple__get_Item "get_Length", // System_Runtime_CompilerServices_ITuple__get_Length ".ctor", // System_InvalidOperationException__ctor - ".ctor", // System_InvalidOperationException__ctorString ".ctor", // System_Runtime_CompilerServices_SwitchExpressionException__ctor ".ctor", // System_Runtime_CompilerServices_SwitchExpressionException__ctorObject "Equals", // System_Threading_CancellationToken__Equals diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.cs.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.cs.xlf index 2fa852c159d6c..4aa76eeed541c 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.cs.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.cs.xlf @@ -39,16 +39,6 @@ Pokud chcete tento analyzátor zakázat, potlačte následující diagnostiku: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. {0} hintName obsahuje neplatný znak {1} na pozici {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.de.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.de.xlf index 364047feec649..00ea4369d37cd 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.de.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.de.xlf @@ -39,16 +39,6 @@ Unterdrücken Sie die folgende Diagnose, um dieses Analysetool zu deaktivieren: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. Der hintName "{0}" enthält ein ungültiges Zeichen "{1}" an Position {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.es.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.es.xlf index 1253ec5496d77..f7b6c0d69253b 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.es.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.es.xlf @@ -39,16 +39,6 @@ Suprima el diagnóstico siguiente para deshabilitar este analizador: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. El elemento hintName "{0}" contiene un carácter no válido "{1}" en la posición {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.fr.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.fr.xlf index 967be7424cccc..5240ce918f8c4 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.fr.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.fr.xlf @@ -39,16 +39,6 @@ Supprimez les diagnostics suivants pour désactiver cet analyseur : {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. Le hintName « {0} » contient un caractère non valide « {1} » à la position {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.it.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.it.xlf index e968e21f33ce0..bc850fd6a3102 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.it.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.it.xlf @@ -39,16 +39,6 @@ Per disabilitare questo analizzatore, eliminare la diagnostica seguente: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. L'elemento hintName '{0}' contiene un carattere non valido '{1}' alla posizione {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ja.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ja.xlf index ada7f1dafc681..75847de1ed2f6 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ja.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ja.xlf @@ -39,16 +39,6 @@ 次の診断を抑制して、このアナライザーを無効にします: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. hintName {0} の位置 {2} に無効な文字 '{1}' が含まれています。 diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ko.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ko.xlf index 03be4626a83c9..097be4f235c04 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ko.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ko.xlf @@ -39,16 +39,6 @@ 이 분석기를 사용하지 않도록 설정하려면 다음 진단이 표시되지 않도록 설정하세요. {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. hintName의 {0} 위치 {2}에 잘못된 문자 '{1}'이(가) 있습니다. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pl.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pl.xlf index bb38bea3940f1..aed49848d2d89 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pl.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pl.xlf @@ -39,16 +39,6 @@ Pomiń następującą diagnostykę, aby wyłączyć ten analizator: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. Element hintName „{0}” zawiera nieprawidłowy znak „{1}” na pozycji {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pt-BR.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pt-BR.xlf index 1c522fba6c113..aa6850941c6ee 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pt-BR.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.pt-BR.xlf @@ -39,16 +39,6 @@ Suprimir os seguintes diagnósticos para desabilitar este analisador: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. O hintName '{0}' contém um caractere inválido '{1}' na posição {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ru.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ru.xlf index 480ee2cc98470..625cd0fd53384 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ru.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.ru.xlf @@ -39,16 +39,6 @@ Отключите следующую диагностику, чтобы отключить этот анализатор: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. hintName "{0}" содержит недопустимый символ "{1}" в позиции {2}. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.tr.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.tr.xlf index 5186af765f636..0fb46e1e726b6 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.tr.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.tr.xlf @@ -39,16 +39,6 @@ Bu çözümleyiciyi devre dışı bırakmak için şu tanılamaları gizleyin: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. hintName '{0}', {2} konumunda geçersiz bir '{1}' karakteri içeriyor. diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hans.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hans.xlf index 9714b0083f904..b22f62b9662fc 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hans.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hans.xlf @@ -39,16 +39,6 @@ 取消以下诊断以禁用此分析器: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. hintName“{0}”在位置 {2} 处包含无效字符“{1}”。 diff --git a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hant.xlf b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hant.xlf index d7100f2db3ca8..fec16f40c1ab8 100644 --- a/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hant.xlf +++ b/src/Compilers/Core/Portable/xlf/CodeAnalysisResources.zh-Hant.xlf @@ -39,16 +39,6 @@ 請隱藏下列診斷以停用此分析器: {0} {0}: Comma-separated list of diagnostic IDs - - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - Edit and Continue can't resume suspended asynchronous method since the corresponding await expression has been deleted - - - - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - Edit and Continue can't resume suspended iterator since the corresponding yield return statement has been deleted - - The hintName '{0}' contains an invalid character '{1}' at position {2}. 位置 {2} 的 hintName {0} 包含無效的字元 '{1}'。 diff --git a/src/Compilers/Test/Core/Compilation/CompilationTestDataExtensions.cs b/src/Compilers/Test/Core/Compilation/CompilationTestDataExtensions.cs index 0a7d4b5916ba8..11e63278c95ab 100644 --- a/src/Compilers/Test/Core/Compilation/CompilationTestDataExtensions.cs +++ b/src/Compilers/Test/Core/Compilation/CompilationTestDataExtensions.cs @@ -108,8 +108,7 @@ internal static EditAndContinueMethodDebugInformation GetEncDebugInfo(this Compi 0, Cci.MetadataWriter.GetLocalSlotDebugInfos(methodData.ILBuilder.LocalSlotManager.LocalsInOrder()), closures: ImmutableArray.Empty, - lambdas: ImmutableArray.Empty, - stateMachineStates: ImmutableArray.Empty); + lambdas: ImmutableArray.Empty); } internal static Func EncDebugInfoProvider(this CompilationTestData.MethodData methodData) diff --git a/src/Compilers/Test/Core/MarkedSource/SourceWithMarkedNodes.cs b/src/Compilers/Test/Core/MarkedSource/SourceWithMarkedNodes.cs index 24bab1d23ddc3..9b30cb6c8da06 100644 --- a/src/Compilers/Test/Core/MarkedSource/SourceWithMarkedNodes.cs +++ b/src/Compilers/Test/Core/MarkedSource/SourceWithMarkedNodes.cs @@ -81,7 +81,7 @@ internal static string ClearTags(string source) } private static readonly Regex s_tags = new Regex( - @"[<][/]?[NMCL][:][:\.A-Za-z0-9]*[>]", + @"[<][/]?[NMCL][:]?[:\.A-Za-z0-9]*[>]", RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline); private static readonly Regex s_markerPattern = new Regex( @@ -93,7 +93,7 @@ internal static string ClearTags(string source) (?[0-9]+) # The first number after the colon is the Id ([.](?[0-9]+))? # Digits after a decimal point are the parent Id ([:](?[A-Za-z]+))? # A second colon separates the syntax kind - ) # Close the group for the things after the tag name + )? # Close the group for the things after the tag name [>] # Close tag ( # Start a group so that the closing tag is optional diff --git a/src/Compilers/VisualBasic/Portable/Compilation/MethodCompiler.vb b/src/Compilers/VisualBasic/Portable/Compilation/MethodCompiler.vb index b3ade194c24dd..8a926154dfff4 100644 --- a/src/Compilers/VisualBasic/Portable/Compilation/MethodCompiler.vb +++ b/src/Compilers/VisualBasic/Portable/Compilation/MethodCompiler.vb @@ -315,7 +315,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic block:=body, lambdaDebugInfo:=ImmutableArray(Of LambdaDebugInfo).Empty, closureDebugInfo:=ImmutableArray(Of ClosureDebugInfo).Empty, - stateMachineStateDebugInfos:=ImmutableArray(Of StateMachineStateDebugInfo).Empty, stateMachineTypeOpt:=Nothing, variableSlotAllocatorOpt:=Nothing, debugDocumentProvider:=Nothing, @@ -887,7 +886,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic block:=boundBody, lambdaDebugInfo:=ImmutableArray(Of LambdaDebugInfo).Empty, closureDebugInfo:=ImmutableArray(Of ClosureDebugInfo).Empty, - stateMachineStateDebugInfos:=ImmutableArray(Of StateMachineStateDebugInfo).Empty, stateMachineTypeOpt:=Nothing, variableSlotAllocatorOpt:=Nothing, debugDocumentProvider:=If(_emitTestCoverageData, _debugDocumentProvider, Nothing), @@ -918,11 +916,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Private Sub CompileSynthesizedMethods(additionalTypes As ImmutableArray(Of NamedTypeSymbol)) Debug.Assert(_moduleBeingBuiltOpt IsNot Nothing) - Dim lambdaDebugInfoBuilder = ArrayBuilder(Of LambdaDebugInfo).GetInstance() - Dim closureDebugInfoBuilder = ArrayBuilder(Of ClosureDebugInfo).GetInstance() - Dim stateMachineStateDebugInfoBuilder = ArrayBuilder(Of StateMachineStateDebugInfo).GetInstance() Dim compilationState As New TypeCompilationState(_compilation, _moduleBeingBuiltOpt, initializeComponentOpt:=Nothing) - For Each additionalType In additionalTypes Dim methodOrdinal As Integer = 0 @@ -937,6 +931,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim lazyVariableSlotAllocator As VariableSlotAllocator = Nothing Dim statemachineTypeOpt As StateMachineTypeSymbol = Nothing + Dim lambdaDebugInfoBuilder = ArrayBuilder(Of LambdaDebugInfo).GetInstance() + Dim closureDebugInfoBuilder = ArrayBuilder(Of ClosureDebugInfo).GetInstance() Dim delegateRelaxationIdDispenser = 0 Dim dynamicAnalysisSpans As ImmutableArray(Of SourceSpan) = ImmutableArray(Of SourceSpan).Empty @@ -953,7 +949,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic lazyVariableSlotAllocator:=lazyVariableSlotAllocator, lambdaDebugInfoBuilder:=lambdaDebugInfoBuilder, closureDebugInfoBuilder:=closureDebugInfoBuilder, - stateMachineStateDebugInfoBuilder:=stateMachineStateDebugInfoBuilder, delegateRelaxationIdDispenser:=delegateRelaxationIdDispenser, stateMachineTypeOpt:=statemachineTypeOpt, allowOmissionOfConditionalCalls:=_moduleBeingBuiltOpt.AllowOmissionOfConditionalCalls, @@ -968,7 +963,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic rewrittenBody, lambdaDebugInfoBuilder.ToImmutable(), closureDebugInfoBuilder.ToImmutable(), - stateMachineStateDebugInfoBuilder.ToImmutable(), statemachineTypeOpt, lazyVariableSlotAllocator, debugDocumentProvider:=Nothing, @@ -977,6 +971,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic emitTestCoverageData:=False, dynamicAnalysisSpans:=dynamicAnalysisSpans) End If + + lambdaDebugInfoBuilder.Free() + closureDebugInfoBuilder.Free() End If _diagnostics.AddRange(diagnosticsThisMethod) @@ -991,10 +988,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic _moduleBeingBuiltOpt.SetMethodBody(method, emittedBody) End If - lambdaDebugInfoBuilder.Clear() - closureDebugInfoBuilder.Clear() - stateMachineStateDebugInfoBuilder.Clear() - methodOrdinal += 1 Next Next @@ -1004,9 +997,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If compilationState.Free() - lambdaDebugInfoBuilder.Free() - closureDebugInfoBuilder.Free() - stateMachineStateDebugInfoBuilder.Free() End Sub Private Sub CompileSynthesizedMethods(compilationState As TypeCompilationState) @@ -1027,7 +1017,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic block:=methodWithBody.Body, lambdaDebugInfo:=ImmutableArray(Of LambdaDebugInfo).Empty, closureDebugInfo:=ImmutableArray(Of ClosureDebugInfo).Empty, - stateMachineStateDebugInfos:=ImmutableArray(Of StateMachineStateDebugInfo).Empty, stateMachineTypeOpt:=Nothing, variableSlotAllocatorOpt:=Nothing, debugDocumentProvider:=_debugDocumentProvider, @@ -1362,7 +1351,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim lambdaDebugInfoBuilder = ArrayBuilder(Of LambdaDebugInfo).GetInstance() Dim closureDebugInfoBuilder = ArrayBuilder(Of ClosureDebugInfo).GetInstance() - Dim stateMachineStateDebugInfoBuilder = ArrayBuilder(Of StateMachineStateDebugInfo).GetInstance() setterBody = Rewriter.LowerBodyOrInitializer(setter, withEventPropertyIdDispenser, @@ -1376,20 +1364,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic lazyVariableSlotAllocator:=Nothing, lambdaDebugInfoBuilder:=lambdaDebugInfoBuilder, closureDebugInfoBuilder:=closureDebugInfoBuilder, - stateMachineStateDebugInfoBuilder:=stateMachineStateDebugInfoBuilder, delegateRelaxationIdDispenser:=delegateRelaxationIdDispenser, stateMachineTypeOpt:=Nothing, allowOmissionOfConditionalCalls:=True, isBodySynthesized:=True) - ' There shall be no lambdas and no awaits/yields in the synthesized accessor but delegate relaxation conversions: - Debug.Assert(lambdaDebugInfoBuilder.IsEmpty()) - Debug.Assert(closureDebugInfoBuilder.IsEmpty()) - Debug.Assert(stateMachineStateDebugInfoBuilder.IsEmpty()) + ' There shall be no lambdas in the synthesized accessor but delegate relaxation conversions: + Debug.Assert(Not lambdaDebugInfoBuilder.Any()) + Debug.Assert(Not closureDebugInfoBuilder.Any()) lambdaDebugInfoBuilder.Free() closureDebugInfoBuilder.Free() - stateMachineStateDebugInfoBuilder.Free() compilationState.AddMethodWrapper(setter, setter, setterBody) _moduleBeingBuiltOpt.AddSynthesizedDefinition(containingType, setter.GetCciAdapter()) @@ -1474,7 +1459,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim allowOmissionOfConditionalCalls = _moduleBeingBuiltOpt Is Nothing OrElse _moduleBeingBuiltOpt.AllowOmissionOfConditionalCalls Dim lambdaDebugInfoBuilder = ArrayBuilder(Of LambdaDebugInfo).GetInstance() Dim closureDebugInfoBuilder = ArrayBuilder(Of ClosureDebugInfo).GetInstance() - Dim stateMachineStateDebugInfoBuilder = ArrayBuilder(Of StateMachineStateDebugInfo).GetInstance() Dim dynamicAnalysisSpans As ImmutableArray(Of SourceSpan) = ImmutableArray(Of SourceSpan).Empty body = Rewriter.LowerBodyOrInitializer(method, @@ -1489,7 +1473,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic lazyVariableSlotAllocator, lambdaDebugInfoBuilder, closureDebugInfoBuilder, - stateMachineStateDebugInfoBuilder, delegateRelaxationIdDispenser, stateMachineTypeOpt, allowOmissionOfConditionalCalls, @@ -1530,7 +1513,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic body, lambdaDebugInfoBuilder.ToImmutable(), closureDebugInfoBuilder.ToImmutable(), - stateMachineStateDebugInfoBuilder.ToImmutable(), stateMachineTypeOpt, lazyVariableSlotAllocator, _debugDocumentProvider, @@ -1558,7 +1540,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic block As BoundStatement, lambdaDebugInfo As ImmutableArray(Of LambdaDebugInfo), closureDebugInfo As ImmutableArray(Of ClosureDebugInfo), - stateMachineStateDebugInfos As ImmutableArray(Of StateMachineStateDebugInfo), stateMachineTypeOpt As StateMachineTypeSymbol, variableSlotAllocatorOpt As VariableSlotAllocator, debugDocumentProvider As DebugDocumentProvider, @@ -1690,7 +1671,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic stateMachineHoistedLocalScopes:=stateMachineHoistedLocalScopes, stateMachineHoistedLocalSlots:=stateMachineHoistedLocalSlots, stateMachineAwaiterSlots:=stateMachineAwaiterSlots, - stateMachineStatesDebugInfo:=StateMachineStatesDebugInfo.Create(variableSlotAllocatorOpt, stateMachineStateDebugInfos), stateMachineMoveNextDebugInfoOpt:=moveNextBodyDebugInfoOpt, dynamicAnalysisDataOpt:=dynamicAnalysisDataOpt) Finally diff --git a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicDefinitionMap.vb b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicDefinitionMap.vb index 98b2a823c3454..1e0f115eadb06 100644 --- a/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicDefinitionMap.vb +++ b/src/Compilers/VisualBasic/Portable/Emit/EditAndContinue/VisualBasicDefinitionMap.vb @@ -124,9 +124,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Emit End If End Function - Protected Overrides Function TryGetStateMachineType(methodHandle As MethodDefinitionHandle) As ITypeSymbolInternal + Protected Overrides Function TryGetStateMachineType(methodHandle As EntityHandle) As ITypeSymbolInternal Dim typeName As String = Nothing - If _metadataDecoder.Module.HasStateMachineAttribute(methodHandle, typeName) Then + If _metadataDecoder.Module.HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncStateMachineAttribute, typeName) OrElse + _metadataDecoder.Module.HasStringValuedAttribute(methodHandle, AttributeDescription.IteratorStateMachineAttribute, typeName) Then + Return _metadataDecoder.GetTypeSymbolForSerializedType(typeName) End If diff --git a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb index 8f15aa7075c26..d67f29bc420c9 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.vb @@ -66,12 +66,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic builder As FieldSymbol, hoistedVariables As IReadOnlySet(Of Symbol), nonReusableLocalProxies As Dictionary(Of Symbol, CapturedSymbolOrExpression), - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, owner As AsyncRewriter, diagnostics As BindingDiagnosticBag) - MyBase.New(F, state, hoistedVariables, nonReusableLocalProxies, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, diagnostics) + MyBase.New(F, state, hoistedVariables, nonReusableLocalProxies, slotAllocatorOpt, diagnostics) Me._method = method Me._builder = builder diff --git a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb index d1032d750de75..80eccb8a90524 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.vb @@ -28,13 +28,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Public Sub New(body As BoundStatement, method As MethodSymbol, stateMachineType As AsyncStateMachine, - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, asyncKind As AsyncMethodKind, compilationState As TypeCompilationState, diagnostics As BindingDiagnosticBag) - MyBase.New(body, method, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) + MyBase.New(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) Me._binder = CreateMethodBinder(method) Me._lookupOptions = LookupOptions.AllMethodsOfAnyArity Or LookupOptions.IgnoreExtensionMethods Or LookupOptions.NoBaseClassLookup @@ -72,7 +71,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Friend Overloads Shared Function Rewrite(body As BoundBlock, method As MethodSymbol, methodOrdinal As Integer, - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, compilationState As TypeCompilationState, diagnostics As BindingDiagnosticBag, @@ -94,7 +92,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType) - Dim rewriter As New AsyncRewriter(body, method, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, asyncMethodKind, compilationState, diagnostics) + Dim rewriter As New AsyncRewriter(body, method, stateMachineType, slotAllocatorOpt, asyncMethodKind, compilationState, diagnostics) ' check if we have all the types we need If rewriter.EnsureAllSymbolsAndSignature() Then @@ -259,7 +257,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic builder:=_builderField, hoistedVariables:=hoistedVariables, nonReusableLocalProxies:=nonReusableLocalProxies, - StateDebugInfoBuilder, slotAllocatorOpt:=SlotAllocatorOpt, owner:=Me, diagnostics:=Diagnostics) diff --git a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb index 2eae48b96e447..ce00cd5b7bf72 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.IteratorMethodToClassRewriter.vb @@ -29,11 +29,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic current As FieldSymbol, hoistedVariables As IReadOnlySet(Of Symbol), localProxies As Dictionary(Of Symbol, FieldSymbol), - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, diagnostics As BindingDiagnosticBag) - MyBase.New(F, state, hoistedVariables, localProxies, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, diagnostics) + MyBase.New(F, state, hoistedVariables, localProxies, slotAllocatorOpt, diagnostics) _current = current End Sub diff --git a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb index 125c80376913d..e5d4b2b0bc25f 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/IteratorRewriter/IteratorRewriter.vb @@ -23,12 +23,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic method As MethodSymbol, isEnumerable As Boolean, stateMachineType As IteratorStateMachine, - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, compilationState As TypeCompilationState, diagnostics As BindingDiagnosticBag) - MyBase.New(body, method, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) + MyBase.New(body, method, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) Me._isEnumerable = isEnumerable @@ -47,7 +46,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Friend Overloads Shared Function Rewrite(body As BoundBlock, method As MethodSymbol, methodOrdinal As Integer, - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, compilationState As TypeCompilationState, diagnostics As BindingDiagnosticBag, @@ -74,7 +72,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic compilationState.ModuleBuilderOpt.CompilationState.SetStateMachineType(method, stateMachineType) - Dim rewriter As New IteratorRewriter(body, method, isEnumerable, stateMachineType, stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics) + Dim rewriter As New IteratorRewriter(body, method, isEnumerable, stateMachineType, slotAllocatorOpt, compilationState, diagnostics) ' check if we have all the types we need If rewriter.EnsureAllSymbolsAndSignature() Then @@ -349,7 +347,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic current:=_currentField, hoistedVariables:=hoistedVariables, localProxies:=nonReusableLocalProxies, - StateDebugInfoBuilder, slotAllocatorOpt:=SlotAllocatorOpt, diagnostics:=Diagnostics) diff --git a/src/Compilers/VisualBasic/Portable/Lowering/LambdaRewriter/LambdaRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/LambdaRewriter/LambdaRewriter.vb index 28fb21526a96d..7a60d299baec6 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/LambdaRewriter/LambdaRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/LambdaRewriter/LambdaRewriter.vb @@ -901,11 +901,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' produce a unique method ordinal for the corresponding state machine type, whose name includes the (unique) method name. Const methodOrdinal As Integer = -1 - Dim stateMachineStateDebugInfosBuilder = ArrayBuilder(Of StateMachineStateDebugInfo).GetInstance() Dim slotAllocatorOpt = CompilationState.ModuleBuilderOpt.TryCreateVariableSlotAllocator(method, method.TopLevelMethod, Diagnostics.DiagnosticBag) - Dim result = Rewriter.RewriteIteratorAndAsync(loweredBody, method, methodOrdinal, CompilationState, Diagnostics, stateMachineStateDebugInfosBuilder, slotAllocatorOpt, stateMachineTypeOpt) - stateMachineStateDebugInfosBuilder.Free() - Return result + Return Rewriter.RewriteIteratorAndAsync(loweredBody, method, methodOrdinal, CompilationState, Diagnostics, slotAllocatorOpt, stateMachineTypeOpt) End Function Public Overrides Function VisitTryCast(node As BoundTryCast) As BoundNode diff --git a/src/Compilers/VisualBasic/Portable/Lowering/Rewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/Rewriter.vb index 9c2f8e72bbf6a..91c2bdff8f81a 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/Rewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/Rewriter.vb @@ -26,7 +26,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ByRef lazyVariableSlotAllocator As VariableSlotAllocator, lambdaDebugInfoBuilder As ArrayBuilder(Of LambdaDebugInfo), closureDebugInfoBuilder As ArrayBuilder(Of ClosureDebugInfo), - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), ByRef delegateRelaxationIdDispenser As Integer, ByRef stateMachineTypeOpt As StateMachineTypeSymbol, allowOmissionOfConditionalCalls As Boolean, @@ -109,7 +108,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Return bodyWithoutLambdas End If - Dim bodyWithoutIteratorAndAsync = RewriteIteratorAndAsync(bodyWithoutLambdas, method, methodOrdinal, compilationState, localDiagnostics, stateMachineStateDebugInfoBuilder, lazyVariableSlotAllocator, stateMachineTypeOpt) + Dim bodyWithoutIteratorAndAsync = RewriteIteratorAndAsync(bodyWithoutLambdas, method, methodOrdinal, compilationState, localDiagnostics, lazyVariableSlotAllocator, stateMachineTypeOpt) diagnostics.AddRangeAndFree(localDiagnostics) @@ -128,7 +127,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic methodOrdinal As Integer, compilationState As TypeCompilationState, diagnostics As BindingDiagnosticBag, - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, ByRef stateMachineTypeOpt As StateMachineTypeSymbol) As BoundBlock @@ -138,7 +136,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim bodyWithoutIterators = IteratorRewriter.Rewrite(bodyWithoutLambdas, method, methodOrdinal, - stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics, @@ -152,7 +149,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim bodyWithoutAsync = AsyncRewriter.Rewrite(bodyWithoutIterators, method, methodOrdinal, - stateMachineStateDebugInfoBuilder, slotAllocatorOpt, compilationState, diagnostics, diff --git a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb index 786aa909d716a..7003970ca9c60 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.StateMachineMethodToClassRewriter.vb @@ -65,13 +65,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ''' Private ReadOnly _hoistedVariables As IReadOnlySet(Of Symbol) = Nothing - Private ReadOnly _stateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo) - Public Sub New(F As SyntheticBoundNodeFactory, stateField As FieldSymbol, hoistedVariables As IReadOnlySet(Of Symbol), initialProxies As Dictionary(Of Symbol, TProxy), - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, diagnostics As BindingDiagnosticBag) @@ -87,7 +84,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Me.StateField = stateField Me.CachedState = F.SynthesizedLocal(F.SpecialType(SpecialType.System_Int32), SynthesizedLocalKind.StateMachineCachedState, F.Syntax) Me._hoistedVariables = hoistedVariables - Me._stateDebugInfoBuilder = stateMachineStateDebugInfoBuilder For Each p In initialProxies Me.Proxies.Add(p.Key, p.Value) diff --git a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.vb index 008be8c2623d7..a36f12afb3185 100644 --- a/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.vb +++ b/src/Compilers/VisualBasic/Portable/Lowering/StateMachineRewriter/StateMachineRewriter.vb @@ -28,7 +28,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Protected ReadOnly StateMachineType As SynthesizedContainer Protected ReadOnly SlotAllocatorOpt As VariableSlotAllocator Protected ReadOnly SynthesizedLocalOrdinals As SynthesizedLocalOrdinalsDispenser - Protected ReadOnly StateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo) Protected StateField As FieldSymbol Protected nonReusableLocalProxies As Dictionary(Of Symbol, TProxy) @@ -39,7 +38,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Protected Sub New(body As BoundStatement, method As MethodSymbol, stateMachineType As StateMachineTypeSymbol, - stateMachineStateDebugInfoBuilder As ArrayBuilder(Of StateMachineStateDebugInfo), slotAllocatorOpt As VariableSlotAllocator, compilationState As TypeCompilationState, diagnostics As BindingDiagnosticBag) @@ -57,7 +55,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Me.SlotAllocatorOpt = slotAllocatorOpt Me.Diagnostics = diagnostics Me.SynthesizedLocalOrdinals = New SynthesizedLocalOrdinalsDispenser() - Me.StateDebugInfoBuilder = stateMachineStateDebugInfoBuilder Me.nonReusableLocalProxies = New Dictionary(Of Symbol, TProxy)() Me.F = New SyntheticBoundNodeFactory(method, method, method.ContainingType, body.Syntax, compilationState, diagnostics) diff --git a/src/Dependencies/CodeAnalysis.Debugging/CustomDebugInfoKind.cs b/src/Dependencies/CodeAnalysis.Debugging/CustomDebugInfoKind.cs index 9be8932163b09..afaf08923233f 100644 --- a/src/Dependencies/CodeAnalysis.Debugging/CustomDebugInfoKind.cs +++ b/src/Dependencies/CodeAnalysis.Debugging/CustomDebugInfoKind.cs @@ -62,10 +62,5 @@ internal enum CustomDebugInfoKind : byte /// C# and VB. Tuple element names for local variables and constants. /// TupleElementNames = 8, - - /// - /// C# and VB. Syntax offsets of nodes associated with state machine states in an async/iterator method and their corresponding state numbers. - /// - EditAndContinueStateMachineStateMap = 9, } } diff --git a/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs b/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs index 4e0e325055ab0..d05cb8526a91b 100644 --- a/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs +++ b/src/Dependencies/CodeAnalysis.Debugging/PortableCustomDebugInfoKinds.cs @@ -17,7 +17,6 @@ internal static class PortableCustomDebugInfoKinds public static readonly Guid DefaultNamespace = new("58b2eab6-209f-4e4e-a22c-b2d0f910c782"); public static readonly Guid EncLocalSlotMap = new("755F52A8-91C5-45BE-B4B8-209571E552BD"); public static readonly Guid EncLambdaAndClosureMap = new("A643004C-0240-496F-A783-30D64F4979DE"); - public static readonly Guid EncStateMachineStateMap = new("8B78CD68-2EDE-420B-980B-E15884B8AAA3"); public static readonly Guid SourceLink = new("CC110556-A091-4D38-9FEC-25AB9A351A6A"); public static readonly Guid EmbeddedSource = new("0E8A571B-6926-466E-B4AD-8AB04611F5FE"); public static readonly Guid CompilationMetadataReferences = new("7E4D4708-096E-4C5C-AEDA-CB10BA6A740D"); diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs index 932effdfbd4e9..4401a643f5afd 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/CompilationExtensions.cs @@ -38,11 +38,20 @@ internal static PEMethodSymbol GetSourceMethod(this CSharpCompilation compilatio { foreach (var member in containingType.ContainingType.GetMembers(sourceMethodName)) { - if (member is PEMethodSymbol candidateMethod && - metadataDecoder.Module.HasStateMachineAttribute(candidateMethod.Handle, out var stateMachineTypeName) && - metadataDecoder.GetTypeSymbolForSerializedType(stateMachineTypeName).OriginalDefinition.Equals(containingType)) + if (member is PEMethodSymbol candidateMethod) { - return candidateMethod; + var module = metadataDecoder.Module; + methodHandle = candidateMethod.Handle; + string stateMachineTypeName; + if (module.HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncStateMachineAttribute, out stateMachineTypeName) || + module.HasStringValuedAttribute(methodHandle, AttributeDescription.IteratorStateMachineAttribute, out stateMachineTypeName) || + module.HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncIteratorStateMachineAttribute, out stateMachineTypeName)) + { + if (metadataDecoder.GetTypeSymbolForSerializedType(stateMachineTypeName).OriginalDefinition.Equals(containingType)) + { + return candidateMethod; + } + } } } } diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs index bb174945a96de..5b1cb9fe323c1 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/EEAssemblyBuilder.cs @@ -12,7 +12,6 @@ using Microsoft.CodeAnalysis.Symbols; using Roslyn.Utilities; using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Reflection.Metadata; @@ -174,13 +173,6 @@ public override bool TryGetPreviousLambda(SyntaxNode lambdaOrLambdaBodySyntax, b return false; } - public override bool TryGetPreviousStateMachineState(SyntaxNode awaitOrYieldSyntax, out int stateOrdinal) - { - stateOrdinal = 0; - return false; - } - - public override int? GetFirstUnusedStateMachineState(bool increasing) => null; public override string? PreviousStateMachineTypeName => null; public override int PreviousHoistedLocalSlotCount => 0; public override int PreviousAwaiterSlotCount => 0; diff --git a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/CompilationExtensions.vb b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/CompilationExtensions.vb index 78ac4b0404922..90096eaf0d461 100644 --- a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/CompilationExtensions.vb +++ b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/CompilationExtensions.vb @@ -35,10 +35,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator For Each member In containingType.ContainingType.GetMembers(sourceMethodName) Dim candidateMethod = TryCast(member, PEMethodSymbol) If candidateMethod IsNot Nothing Then + Dim [module] = metadataDecoder.Module + methodHandle = candidateMethod.Handle Dim stateMachineTypeName As String = Nothing - If metadataDecoder.Module.HasStateMachineAttribute(candidateMethod.Handle, stateMachineTypeName) AndAlso - metadataDecoder.GetTypeSymbolForSerializedType(stateMachineTypeName).OriginalDefinition.Equals(containingType) Then - Return candidateMethod + If [module].HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncStateMachineAttribute, stateMachineTypeName) OrElse + [module].HasStringValuedAttribute(methodHandle, AttributeDescription.IteratorStateMachineAttribute, stateMachineTypeName) OrElse + [module].HasStringValuedAttribute(methodHandle, AttributeDescription.AsyncIteratorStateMachineAttribute, stateMachineTypeName) _ + Then + If metadataDecoder.GetTypeSymbolForSerializedType(stateMachineTypeName).OriginalDefinition.Equals(containingType) Then + Return candidateMethod + End If End If End If Next diff --git a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb index aad85d9ce0e75..4e2cb1a42a5b5 100644 --- a/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb +++ b/src/ExpressionEvaluator/VisualBasic/Source/ExpressionCompiler/EEAssemblyBuilder.vb @@ -191,15 +191,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator Return False End Function - Public Overrides Function TryGetPreviousStateMachineState(awaitOrYieldSyntax As SyntaxNode, ByRef stateOrdinal As Integer) As Boolean - stateOrdinal = 0 - Return False - End Function - - Public Overrides Function GetFirstUnusedStateMachineState(increasing As Boolean) As Integer? - Return Nothing - End Function - Public Overrides ReadOnly Property PreviousStateMachineTypeName As String Get Return Nothing diff --git a/src/Features/Core/Portable/EditAndContinue/EditAndContinueMethodDebugInfoReader.cs b/src/Features/Core/Portable/EditAndContinue/EditAndContinueMethodDebugInfoReader.cs index cbc870e77d4dc..98917b86fbc76 100644 --- a/src/Features/Core/Portable/EditAndContinue/EditAndContinueMethodDebugInfoReader.cs +++ b/src/Features/Core/Portable/EditAndContinue/EditAndContinueMethodDebugInfoReader.cs @@ -81,19 +81,18 @@ public override EditAndContinueMethodDebugInformation GetDebugInfo(MethodDefinit try { - ImmutableArray localSlots, lambdaMap, stateMachineSuspensionPoints; + ImmutableArray localSlots, lambdaMap; if (debugInfo != null) { localSlots = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(debugInfo, CustomDebugInfoKind.EditAndContinueLocalSlotMap); lambdaMap = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(debugInfo, CustomDebugInfoKind.EditAndContinueLambdaMap); - stateMachineSuspensionPoints = CustomDebugInfoReader.TryGetCustomDebugInfoRecord(debugInfo, CustomDebugInfoKind.EditAndContinueStateMachineStateMap); } else { - localSlots = lambdaMap = stateMachineSuspensionPoints = default; + localSlots = lambdaMap = default; } - return EditAndContinueMethodDebugInformation.Create(localSlots, lambdaMap, stateMachineSuspensionPoints); + return EditAndContinueMethodDebugInformation.Create(localSlots, lambdaMap); } catch (InvalidOperationException e) when (FatalError.ReportAndCatch(e)) // likely a bug in the compiler/debugger { @@ -121,8 +120,7 @@ public override StandaloneSignatureHandle GetLocalSignature(MethodDefinitionHand public override EditAndContinueMethodDebugInformation GetDebugInfo(MethodDefinitionHandle methodHandle) => EditAndContinueMethodDebugInformation.Create( compressedSlotMap: GetCdiBytes(methodHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap), - compressedLambdaMap: GetCdiBytes(methodHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap), - compressedStateMachineStateMap: GetCdiBytes(methodHandle, PortableCustomDebugInfoKinds.EncStateMachineStateMap)); + compressedLambdaMap: GetCdiBytes(methodHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap)); private ImmutableArray GetCdiBytes(MethodDefinitionHandle methodHandle, Guid kind) => TryGetCustomDebugInformation(_pdbReader, methodHandle, kind, out var cdi) ? diff --git a/src/Test/PdbUtilities/Reader/PdbTestUtilities.cs b/src/Test/PdbUtilities/Reader/PdbTestUtilities.cs index eeb34443188e0..0845b48e57a42 100644 --- a/src/Test/PdbUtilities/Reader/PdbTestUtilities.cs +++ b/src/Test/PdbUtilities/Reader/PdbTestUtilities.cs @@ -47,8 +47,7 @@ ImmutableArray GetCdiBytes(Guid kind) => return EditAndContinueMethodDebugInformation.Create( compressedSlotMap: GetCdiBytes(PortableCustomDebugInfoKinds.EncLocalSlotMap), - compressedLambdaMap: GetCdiBytes(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap), - compressedStateMachineStateMap: GetCdiBytes(PortableCustomDebugInfoKinds.EncStateMachineStateMap)); + compressedLambdaMap: GetCdiBytes(PortableCustomDebugInfoKinds.EncLambdaAndClosureMap)); } } diff --git a/src/Test/PdbUtilities/Reader/PdbValidation.cs b/src/Test/PdbUtilities/Reader/PdbValidation.cs index 4d86ef5f9ec7c..37fc37f00f6e1 100644 --- a/src/Test/PdbUtilities/Reader/PdbValidation.cs +++ b/src/Test/PdbUtilities/Reader/PdbValidation.cs @@ -642,7 +642,7 @@ internal static void VerifyPdbLambdasAndClosures(this Compilation compilation, S expectedTags.Sort((x, y) => x.StartIndex.CompareTo(y.StartIndex)); // Ensure the tag for the method start is the first element - expectedTags.Insert(0, new { Tag = "", StartIndex = methodStart }); + expectedTags.Insert(0, new { Tag = "", StartIndex = methodStart }); // Now reverse the list so we can insert without worrying about offsets expectedTags.Reverse();