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 Compilation?CreateCompilation( TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLogger, ImmutableArray <AnalyzerConfigOptionsResult> analyzerConfigOptions, AnalyzerConfigOptionsResult globalConfigOptions) { var parseOptions = Arguments.ParseOptions; // We compute script parse options once so we don't have to do it repeatedly in // case there are many script files. var scriptParseOptions = parseOptions.WithKind(SourceCodeKind.Script); bool hadErrors = false; var sourceFiles = Arguments.SourceFiles; var trees = new SyntaxTree?[sourceFiles.Length]; var normalizedFilePaths = new string[sourceFiles.Length]; var diagnosticBag = DiagnosticBag.GetInstance(); if (Arguments.CompilationOptions.ConcurrentBuild) { RoslynParallel.For( 0, sourceFiles.Length, UICultureUtilities.WithCurrentUICulture <int>(i => { //NOTE: order of trees is important!! trees[i] = ParseFile( parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], diagnosticBag, out normalizedFilePaths[i]); }), CancellationToken.None); } else { for (int i = 0; i < sourceFiles.Length; i++) { //NOTE: order of trees is important!! trees[i] = ParseFile( parseOptions, scriptParseOptions, ref hadErrors, sourceFiles[i], diagnosticBag, out normalizedFilePaths[i]); } } // If errors had been reported in ParseFile, while trying to read files, then we should simply exit. if (ReportDiagnostics(diagnosticBag.ToReadOnlyAndFree(), consoleOutput, errorLogger)) { Debug.Assert(hadErrors); return(null); } var diagnostics = new List <DiagnosticInfo>(); var uniqueFilePaths = new HashSet <string>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < sourceFiles.Length; i++) { var normalizedFilePath = normalizedFilePaths[i]; Debug.Assert(normalizedFilePath != null); Debug.Assert(sourceFiles[i].IsInputRedirected || PathUtilities.IsAbsolute(normalizedFilePath)); if (!uniqueFilePaths.Add(normalizedFilePath)) { // warning CS2002: Source file '{0}' specified multiple times diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.WRN_FileAlreadyIncluded, Arguments.PrintFullPaths ? normalizedFilePath : _diagnosticFormatter.RelativizeNormalizedPath(normalizedFilePath))); trees[i] = null; } } if (Arguments.TouchedFilesPath != null) { foreach (var path in uniqueFilePaths) { touchedFilesLogger.AddRead(path); } } var assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default; var appConfigPath = this.Arguments.AppConfigPath; if (appConfigPath != null) { try { using (var appConfigStream = new FileStream(appConfigPath, FileMode.Open, FileAccess.Read)) { assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream); } if (touchedFilesLogger != null) { touchedFilesLogger.AddRead(appConfigPath); } } catch (Exception ex) { diagnostics.Add(new DiagnosticInfo(MessageProvider, (int)ErrorCode.ERR_CantReadConfigFile, appConfigPath, ex.Message)); } } var xmlFileResolver = new LoggingXmlFileResolver(Arguments.BaseDirectory, touchedFilesLogger); var sourceFileResolver = new LoggingSourceFileResolver(ImmutableArray <string> .Empty, Arguments.BaseDirectory, Arguments.PathMap, touchedFilesLogger); MetadataReferenceResolver referenceDirectiveResolver; var resolvedReferences = ResolveMetadataReferences(diagnostics, touchedFilesLogger, out referenceDirectiveResolver); if (ReportDiagnostics(diagnostics, consoleOutput, errorLogger)) { return(null); } var loggingFileSystem = new LoggingStrongNameFileSystem(touchedFilesLogger, _tempDirectory); var optionsProvider = new CompilerSyntaxTreeOptionsProvider(trees, analyzerConfigOptions, globalConfigOptions); return(CSharpCompilation.Create( Arguments.CompilationName, trees.WhereNotNull(), resolvedReferences, Arguments.CompilationOptions .WithMetadataReferenceResolver(referenceDirectiveResolver) .WithAssemblyIdentityComparer(assemblyIdentityComparer) .WithXmlReferenceResolver(xmlFileResolver) .WithStrongNameProvider(Arguments.GetStrongNameProvider(loggingFileSystem)) .WithSourceReferenceResolver(sourceFileResolver) .WithSyntaxTreeOptionsProvider(optionsProvider))); }