diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index 8719059823cacf46d2a4ba101a86d3776ccbfb10..51b522b959fed1c0ef2885193e095e7f8339b92b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -468,6 +468,9 @@ internal override void ForceComplete(SourceLocation locationOpt, CancellationTok var diagnostics = DiagnosticBag.GetInstance(); AfterMembersChecks(diagnostics); AddDeclarationDiagnostics(diagnostics); + + // We may produce a SymbolDeclaredEvent for the enclosing type before events for its contained members + DeclaringCompilation.SymbolDeclaredEvent(this); var thisThreadCompleted = state.NotePartComplete(CompletionPart.FinishMemberChecks); Debug.Assert(thisThreadCompleted); diagnostics.Free(); @@ -510,10 +513,7 @@ internal override void ForceComplete(SourceLocation locationOpt, CancellationTok // We've completed all members, so we're ready for the PointedAtManagedTypeChecks; // proceed to the next iteration. - if (state.NotePartComplete(CompletionPart.MembersCompleted)) - { - DeclaringCompilation.SymbolDeclaredEvent(this); - } + state.NotePartComplete(CompletionPart.MembersCompleted); break; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index 6f588cf2671f0f39529d5bdd6180ea891613f92c..7eae1e9bbba0e2e06adce6480b6556754f1bf1d2 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -390,10 +390,14 @@ protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellat if (!this.IsAsync) { - state.NotePartComplete(CompletionPart.StartAsyncMethodChecks); - if (state.NotePartComplete(CompletionPart.FinishAsyncMethodChecks) && IsPartialDefinition) + if (state.NotePartComplete(CompletionPart.StartAsyncMethodChecks)) { - DeclaringCompilation.SymbolDeclaredEvent(this); + if (IsPartialDefinition) DeclaringCompilation.SymbolDeclaredEvent(this); + state.NotePartComplete(CompletionPart.FinishAsyncMethodChecks); + } + else + { + state.SpinWaitComplete(CompletionPart.FinishAsyncMethodChecks, cancellationToken); } return; @@ -431,10 +435,8 @@ protected sealed override void LazyAsyncMethodChecks(CancellationToken cancellat if (state.NotePartComplete(CompletionPart.StartAsyncMethodChecks)) { AddDeclarationDiagnostics(diagnostics); - if (state.NotePartComplete(CompletionPart.FinishAsyncMethodChecks) && IsPartialDefinition) - { - DeclaringCompilation.SymbolDeclaredEvent(this); - } + if (IsPartialDefinition) DeclaringCompilation.SymbolDeclaredEvent(this); + state.NotePartComplete(CompletionPart.FinishAsyncMethodChecks); } else { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs index a51f2169fbdb64298a1d8e7ad40c9d6e6a05abf4..1382f51ab5133b6b620a3de3acf28f8fa30c3ce0 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs @@ -228,8 +228,10 @@ internal override NamespaceExtent Extent // NOTE: the following is not cancellable. Once we've set the // members, we *must* do the following to make sure we're in a consistent state. this.DeclaringCompilation.DeclarationDiagnostics.AddRange(diagnostics); - RegisterDeclaredCorTypes(); + + // We may produce a SymbolDeclaredEvent for the enclosing namespace before events for its contained members + DeclaringCompilation.SymbolDeclaredEvent(this); _state.NotePartComplete(CompletionPart.NameToMembersMap); } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol_Completion.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol_Completion.cs index 26968bad4e1615ae2d48f38d190a028bece0574e..5940ee3831989cad595643dd21f6d49bfce1768f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol_Completion.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol_Completion.cs @@ -76,10 +76,7 @@ internal override void ForceComplete(SourceLocation locationOpt, CancellationTok if (allCompleted) { - if (_state.NotePartComplete(CompletionPart.MembersCompleted)) - { - DeclaringCompilation.SymbolDeclaredEvent(this); - } + _state.NotePartComplete(CompletionPart.MembersCompleted); break; } else diff --git a/src/Compilers/CSharp/Test/Semantic/Diagnostics/GetDiagnosticsTests.cs b/src/Compilers/CSharp/Test/Semantic/Diagnostics/GetDiagnosticsTests.cs index 57eaba3ebe4eb8f8060bc6aef1a785bf1bf0b709..8137aac7301e4c64b051ba18aae946e0ea693a26 100644 --- a/src/Compilers/CSharp/Test/Semantic/Diagnostics/GetDiagnosticsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Diagnostics/GetDiagnosticsTests.cs @@ -127,7 +127,7 @@ public void Foo() Assert.Equal(4, info.WarningLevel); } - [Fact(Skip ="7446"), WorkItem(7446, "https://github.com/dotnet/roslyn/issues/7446")] + [Fact, WorkItem(7446, "https://github.com/dotnet/roslyn/issues/7446")] public void TestCompilationEventQueueWithSemanticModelGetDiagnostics() { var source1 = @" @@ -155,10 +155,8 @@ partial class Class var compilation = CreateCompilationWithMscorlib45(new[] { tree1, tree2 }).WithEventQueue(eventQueue); // Invoke SemanticModel.GetDiagnostics to force populate the event queue for symbols in the first source file. - var tree = compilation.SyntaxTrees.Single(t => t == tree1); - var root = tree.GetRoot(); - var model = compilation.GetSemanticModel(tree); - model.GetDiagnostics(root.FullSpan); + var model = compilation.GetSemanticModel(tree1); + model.GetDiagnostics(tree1.GetRoot().FullSpan); Assert.True(eventQueue.Count > 0); bool compilationStartedFired; @@ -171,10 +169,10 @@ partial class Class Assert.True(declaredSymbolNames.Contains("N1")); Assert.True(declaredSymbolNames.Contains("Class")); Assert.True(declaredSymbolNames.Contains("NonPartialMethod1")); - Assert.True(completedCompilationUnits.Contains(tree.FilePath)); + Assert.True(completedCompilationUnits.Contains(tree1.FilePath)); } - [Fact(Skip = "7446"), WorkItem(7446, "https://github.com/dotnet/roslyn/issues/7446")] + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/7477"), WorkItem(7477, "https://github.com/dotnet/roslyn/issues/7477")] public void TestCompilationEventsForPartialMethod() { var source1 = @" @@ -204,10 +202,8 @@ partial class Class var compilation = CreateCompilationWithMscorlib45(new[] { tree1, tree2 }).WithEventQueue(eventQueue); // Invoke SemanticModel.GetDiagnostics to force populate the event queue for symbols in the first source file. - var tree = compilation.SyntaxTrees.Single(t => t == tree1); - var root = tree.GetRoot(); - var model = compilation.GetSemanticModel(tree); - model.GetDiagnostics(root.FullSpan); + var model = compilation.GetSemanticModel(tree1); + model.GetDiagnostics(tree1.GetRoot().FullSpan); Assert.True(eventQueue.Count > 0); bool compilationStartedFired; @@ -221,7 +217,7 @@ partial class Class Assert.True(declaredSymbolNames.Contains("Class")); Assert.True(declaredSymbolNames.Contains("NonPartialMethod1")); Assert.True(declaredSymbolNames.Contains("PartialMethod")); - Assert.True(completedCompilationUnits.Contains(tree.FilePath)); + Assert.True(completedCompilationUnits.Contains(tree1.FilePath)); } private static bool DequeueCompilationEvents(AsyncQueue eventQueue, out bool compilationStartedFired, out HashSet declaredSymbolNames, out HashSet completedCompilationUnits) @@ -247,7 +243,8 @@ private static bool DequeueCompilationEvents(AsyncQueue eventQ var symbolDeclaredEvent = compEvent as SymbolDeclaredCompilationEvent; if (symbolDeclaredEvent != null) { - Assert.True(declaredSymbolNames.Add(symbolDeclaredEvent.Symbol.Name), "Unexpected multiple symbol declared events for same symbol"); + var added = declaredSymbolNames.Add(symbolDeclaredEvent.Symbol.Name); + Assert.True(added, "Unexpected multiple symbol declared events for symbol " + symbolDeclaredEvent.Symbol); } else {