internal bool HasComplete(CompletionPart part) { // completeParts is used as a flag indicating completion of other assignments // Volatile.Read is used to ensure the read is not reordered/optimized to happen // before the writes. return((_completeParts & (int)part) == (int)part); }
public void TestNextCompletionPart() { SymbolCompletionState state = new SymbolCompletionState(); Action reader = () => { while (state.IncompleteParts != 0) { Assert.True(SymbolCompletionState.HasAtMostOneBitSet((int)state.NextIncompletePart)); } }; Action writers = () => { Parallel.For(0, Math.Max(1, Environment.ProcessorCount - 1), t => { Random r = new Random(t); while (state.IncompleteParts != 0) { CompletionPart part = (CompletionPart)(1 << r.Next(8 * sizeof(CompletionPart))); state.NotePartComplete(part); } }); }; for (int i = 0; i < 1000; i++) { Parallel.Invoke(reader, writers); } }
internal bool HasComplete(CompletionPart part) { // completeParts is used as a flag indicating completion of other assignments // Volatile.Read is used to ensure the read is not reordered/optimized to happen // before the writes. return (_completeParts & (int)part) == (int)part; }
internal bool NotePartComplete(CompletionPart part) { // passing volatile completeParts byref is ok here. // ThreadSafeFlagOperations.Set performs interlocked assignments #pragma warning disable 0420 return ThreadSafeFlagOperations.Set(ref _completeParts, (int)part); #pragma warning restore 0420 }
internal bool NotePartComplete(CompletionPart part) { // passing volatile completeParts byref is ok here. // ThreadSafeFlagOperations.Set performs interlocked assignments #pragma warning disable 0420 return(ThreadSafeFlagOperations.Set(ref _completeParts, (int)part)); #pragma warning restore 0420 }
internal void SpinWaitComplete(CompletionPart part, CancellationToken cancellationToken) { if (HasComplete(part)) { return; } // Don't return until we've seen all of the requested CompletionParts. This ensures all // diagnostics have been reported (not necessarily on this thread). var spinWait = new SpinWait(); while (!HasComplete(part)) { cancellationToken.ThrowIfCancellationRequested(); spinWait.SpinOnce(); } }
protected virtual CompletionGraphBuilder ConstructCompletionGraph() { return(CompletionPart.ConstructDefaultCompletionGraph()); }
internal override void ForceComplete(SourceLocation locationOpt, CancellationToken cancellationToken) { while (true) { cancellationToken.ThrowIfCancellationRequested(); var incompletePart = _state.NextIncompletePart; switch (incompletePart) { case CompletionPart.NameToMembersMap: { var tmp = GetNameToMembersMap(); } break; case CompletionPart.MembersCompleted: { // ensure relevant imports are complete. foreach (var declaration in _mergedDeclaration.Declarations) { if (locationOpt == null || locationOpt.SourceTree == declaration.SyntaxReference.SyntaxTree) { if (declaration.HasUsings || declaration.HasExternAliases) { this.DeclaringCompilation.GetImports(declaration).Complete(cancellationToken); } } } var members = this.GetMembers(); bool allCompleted = true; if (this.DeclaringCompilation.Options.ConcurrentBuild) { RoslynParallel.For( 0, members.Length, UICultureUtilities.WithCurrentUICulture <int>(i => ForceCompleteMemberByLocation(locationOpt, members[i], cancellationToken)), cancellationToken); foreach (var member in members) { if (!member.HasComplete(CompletionPart.All)) { allCompleted = false; break; } } } else { foreach (var member in members) { ForceCompleteMemberByLocation(locationOpt, member, cancellationToken); allCompleted = allCompleted && member.HasComplete(CompletionPart.All); } } if (allCompleted) { _state.NotePartComplete(CompletionPart.MembersCompleted); break; } else { // NOTE: we're going to kick out of the completion part loop after this, // so not making progress isn't a problem. goto done; } } case CompletionPart.None: return; default: // any other values are completion parts intended for other kinds of symbols _state.NotePartComplete(CompletionPart.All & ~CompletionPart.NamespaceSymbolAll); break; } _state.SpinWaitComplete(incompletePart, cancellationToken); } done: // Don't return until we've seen all of the CompletionParts. This ensures all // diagnostics have been reported (not necessarily on this thread). CompletionPart allParts = (locationOpt == null) ? CompletionPart.NamespaceSymbolAll : CompletionPart.NamespaceSymbolAll & ~CompletionPart.MembersCompleted; _state.SpinWaitComplete(allParts, cancellationToken); }
public override bool HasComplete(CompletionPart part) { return(_state.HasComplete(part)); }
internal sealed override bool HasComplete(CompletionPart part) => state.HasComplete(part);
internal override bool HasComplete(CompletionPart part) { return _state.HasComplete(part); }
internal override void ForceComplete( SourceLocation locationOpt, CancellationToken cancellationToken) { while (true) { // NOTE: cases that depend on GetMembers[ByName] should call RequireCompletionPartMembers. cancellationToken.ThrowIfCancellationRequested(); var incompletePart = NextIncompletePart; switch (incompletePart) { case CompletionPart.MetadataName: case CompletionPart.Attributes: { base.ForceComplete(locationOpt, cancellationToken); } break; case CompletionPart.StartBaseType: case CompletionPart.FinishBaseType: { if (NotePartComplete(CompletionPart.StartBaseType)) { var diagnostics = DiagnosticBag.GetInstance(); CheckBase(diagnostics); AddSemanticDiagnostics(diagnostics); NotePartComplete(CompletionPart.FinishBaseType); diagnostics.Free(); } } break; case CompletionPart.StartInterfaces: case CompletionPart.FinishInterfaces: { if (NotePartComplete(CompletionPart.StartInterfaces)) { var diagnostics = DiagnosticBag.GetInstance(); CheckInterfaces(diagnostics); AddSemanticDiagnostics(diagnostics); NotePartComplete(CompletionPart.FinishInterfaces); diagnostics.Free(); } } break; case CompletionPart.TypeArguments: { var tmp = this.TypeArguments; // force type arguments } break; case CompletionPart.TypeParameters: { // force type parameters foreach (var typeParameter in this.TypeParameters) { typeParameter.ForceComplete(locationOpt, cancellationToken); } NotePartComplete(CompletionPart.TypeParameters); } break; case CompletionPart.Members: { var tmp = this.GetMembersByName(); } break; case CompletionPart.TypeMembers: { var tmp = this.GetTypeMembers(); } break; case CompletionPart.SynthesizedExplicitImplementations: { var tmp = this.GetSynthesizedExplicitImplementations(cancellationToken); //force interface and base class errors to be checked } break; case CompletionPart.StartMemberChecks: case CompletionPart.FinishMemberChecks: { if (NotePartComplete(CompletionPart.StartMemberChecks)) { var diagnostics = DiagnosticBag.GetInstance(); AfterMembersChecks(diagnostics); AddSemanticDiagnostics(diagnostics); NotePartComplete(CompletionPart.FinishMemberChecks); diagnostics.Free(); } } break; case CompletionPart.MembersCompleted: { ReadOnlyArray <Symbol> members = this.GetMembersUnordered(); bool allCompleted = true; if (locationOpt == null) { foreach (var member in members) { cancellationToken.ThrowIfCancellationRequested(); member.ForceComplete(locationOpt, cancellationToken); } } else { foreach (var member in members) { foreach (var loc in member.Locations) { cancellationToken.ThrowIfCancellationRequested(); var sloc = loc as SourceLocation; if (sloc == null) { continue; } if (loc.SourceTree.Equals(locationOpt.SourceTree) && loc.SourceSpan.IntersectsWith(locationOpt.SourceSpan)) { member.ForceComplete(locationOpt, cancellationToken); break; } } allCompleted &= member.HasComplete(CompletionPart.All); } } if (!allCompleted) { // We did not complete all members so we won't have enough information for // the PointedAtManagedTypeChecks, so just kick out now. goto done; } // We've completed all members, so we're ready for the PointedAtManagedTypeChecks; // proceed to the next iteration. NotePartComplete(CompletionPart.MembersCompleted); break; } case CompletionPart.None: return; default: // any other values are completion parts intended for other kinds of symbols NotePartComplete(CompletionPart.All & ~CompletionPart.NamedTypeSymbolAll); break; } SpinWaitComplete(incompletePart, cancellationToken); } done: // Don't return until we've seen all of the CompletionParts. This ensures all // diagnostics have been reported (not necessarily on this thread). CompletionPart allParts = (locationOpt == null) ? CompletionPart.NamedTypeSymbolAll : CompletionPart.NamedTypeSymbolWithLocationAll; SpinWaitComplete(allParts, cancellationToken); }
internal sealed override bool HasComplete(CompletionPart part) { return state.HasComplete(part); }
internal override bool HasComplete(CompletionPart part) => _underlyingField.HasComplete(part);
internal sealed override bool HasComplete(CompletionPart part) { return(_state.HasComplete(part)); }
internal virtual bool HasComplete(CompletionPart part) { // must be overridden by source symbols, no-op for other symbols Debug.Assert(!this.RequiresCompletion); return(true); }