private static ImmutableDictionary<string, ImmutableDictionary<DiagnosticAnalyzer, ProviderId>> CreateAnalyzerIdMap( AnalyzerManager analyzerManager, string language) { var index = 0; var map = ImmutableDictionary.CreateBuilder<string, ImmutableDictionary<DiagnosticAnalyzer, ProviderId>>(); foreach (var kv in analyzerManager.GetHostDiagnosticAnalyzersPerReference(language)) { var perAnalyzerMap = ImmutableDictionary.CreateBuilder<DiagnosticAnalyzer, ProviderId>(); var referenceIdentity = kv.Key; var perLanguageAnalyzers = kv.Value; if (perLanguageAnalyzers.Length > 0) { foreach (var analyzer in perLanguageAnalyzers) { var analyzerId = index++; perAnalyzerMap.Add(analyzer, analyzerId); } map.Add(referenceIdentity, perAnalyzerMap.ToImmutable()); } } return map.ToImmutable(); }
public DiagnosticIncrementalAnalyzer(DiagnosticAnalyzerService owner, int correlationId, Workspace workspace, AnalyzerManager analyzerManager) { _correlationId = correlationId; _owner = owner; _workspace = workspace; _analyzerManager = analyzerManager; }
public DiagnosticAnalyzersAndStates(DiagnosticIncrementalAnalyzer owner, Workspace workspace, AnalyzerManager analyzerManager) { _owner = owner; _sharedAnalyzersAndStates = new WorkspaceAnalyzersAndStates(analyzerManager); _projectAnalyzersAndStatesMap = new ConcurrentDictionary<ProjectId, ProjectAnalyzersAndStates>(); this.Workspace = workspace; }
public PerLanguageAnalyzersAndStates(AnalyzerManager analyzerManager, string language) { _language = language; // TODO: dynamically re-order providers so that cheap one runs first and slower runs later. _diagnosticAnalyzerIdMap = CreateAnalyzerIdMap(analyzerManager, language); _analyzerCount = _diagnosticAnalyzerIdMap.Values.Flatten().Count(); _diagnosticStateMaps = new DiagnosticState[s_stateTypeCount, _analyzerCount]; }
public DiagnosticIncrementalAnalyzer(DiagnosticAnalyzerService owner, int correlationId, Workspace workspace, AnalyzerManager analyzerManager) { _owner = owner; _correlationId = correlationId; _memberRangeMap = new MemberRangeMap(); _analyzersAndState = new DiagnosticAnalyzersAndStates(this, workspace, analyzerManager); _executor = new AnalyzerExecutor(this); _diagnosticLogAggregator = new DiagnosticLogAggregator(_owner); }
private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsInteractive); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return(Failed); } var diagnostics = new List <DiagnosticInfo>(); var analyzers = ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnostics, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; try { Func <ImmutableArray <Diagnostic> > getAnalyzerDiagnostics = null; if (!analyzers.IsDefaultOrEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); var analyzerExceptionDiagnostics = new ConcurrentSet <Diagnostic>(); Action <Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray.Create <AdditionalText, AdditionalTextFile>(additionalTextFiles)); var analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, out compilation, analyzerCts.Token); getAnalyzerDiagnostics = () => { var analyzerDiagnostics = analyzerDriver.GetDiagnosticsAsync().Result; return(analyzerDiagnostics.AddRange(analyzerExceptionDiagnostics)); }; } // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } EmitResult emitResult; // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists string finalOutputPath; string finalPdbFilePath; string finalXmlFilePath; FileStream xmlStreamOpt = null; cancellationToken.ThrowIfCancellationRequested(); finalXmlFilePath = Arguments.DocumentationPath; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xmlStreamOpt == null) { return(Failed); } xmlStreamOpt.SetLength(0); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable <DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) using (xmlStreamOpt) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); finalOutputPath = Path.Combine(Arguments.OutputDirectory, outputName); finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalOutputPath, ".pdb"); // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalOutputPath, streamCreatedByNativePdbWriter: false)) using (var pdbStreamProviderOpt = Arguments.EmitPdb ? new CompilerEmitStreamProvider(this, finalOutputPath, streamCreatedByNativePdbWriter: true) : null) { emitResult = compilation.Emit( peStreamProvider, pdbStreamProviderOpt, (xmlStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(xmlStreamOpt) : null, (win32ResourceStreamOpt != null) ? new Compilation.SimpleEmitStreamProvider(win32ResourceStreamOpt) : null, Arguments.ManifestResources, emitOptions, getAnalyzerDiagnostics, cancellationToken); if (emitResult.Success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalOutputPath); } } } GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics); if (ReportErrors(emitResult.Diagnostics, consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } } return(Succeeded); }
private IProjectAnalyzer GetProjectAnalyzer(string projectFile, StringWriter log, AnalyzerManager manager = null) { // The path will get normalized inside the .GetProject() call below string projectPath = GetFullPath(projectFile); if (manager == null) { manager = new AnalyzerManager(new AnalyzerManagerOptions { LogWriter = log }); } return(manager.GetProject(projectPath)); }
ProjectAnalyzer(AnalyzerManager manager, IEnumerable <string> projectFiles) => _analyzers = projectFiles.Select(manager.GetProject).ToArray();
private static Project Create(AnalyzerManager manager, Options options, string projectFile) { var analyzer = manager.GetProject(projectFile); var msBuildProject = analyzer.Load(); var assemblyFile = msBuildProject.GetItems("IntermediateAssembly").FirstOrDefault()?.EvaluatedInclude; if (assemblyFile == null) { // Not all projects may produce an assembly return(null); } var projectDirectory = Path.GetDirectoryName(projectFile); var assemblyFileFullPath = Path.GetFullPath(Path.Combine(projectDirectory, assemblyFile)); if (!File.Exists(assemblyFileFullPath)) { // Can't analyze this project since it hasn't been built Console.WriteLine($"Assembly did not exist. Ensure you've previously built it. Assembly: {assemblyFileFullPath}"); return(null); } var assembly = LoadAssembly(assemblyFileFullPath); if (assembly == null) { // Can't analyze this project since we couldn't load its assembly Console.WriteLine($"Assembly could not be loaded. Assembly: {assemblyFileFullPath}"); return(null); } var assemblyReferences = assembly .GetReferencedAssemblies() .Select(name => name.Name) .ToHashSet(StringComparer.OrdinalIgnoreCase); var references = msBuildProject .GetItems("Reference") .Select(reference => reference.EvaluatedInclude) .ToList(); var projectReferences = msBuildProject .GetItems("ProjectReference") .Select(reference => reference.EvaluatedInclude) .Select(projectReference => GetProject(manager, options, Path.GetFullPath(Path.Combine(projectDirectory, projectReference)))) .Where(dependency => dependency != null) .ToList(); var packageReferences = msBuildProject .GetItems("PackageReference") .Select(reference => reference.EvaluatedInclude) .ToList(); // Certain project types may require references simply to copy them to the output folder to satisfy transitive dependencies. if (NeedsTransitiveAssemblyReferences(msBuildProject)) { projectReferences.ForEach(projectReference => assemblyReferences.UnionWith(projectReference.AssemblyReferences)); } // Only bother doing a design-time build if there is a reason to var packageAssemblies = new Dictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase); if (packageReferences.Count > 0) { if (options.MsBuildBinlog) { analyzer.WithBinaryLog(); } var msBuildCompiledProject = analyzer.Compile(); var packageParents = msBuildCompiledProject.GetItems("_ActiveTFMPackageDependencies") .Where(package => !string.IsNullOrEmpty(package.GetMetadataValue("ParentPackage"))) .GroupBy( package => { var packageIdentity = package.EvaluatedInclude; return(packageIdentity.Substring(0, packageIdentity.IndexOf('/'))); }, package => { var parentPackageIdentity = package.GetMetadataValue("ParentPackage"); return(parentPackageIdentity.Substring(0, parentPackageIdentity.IndexOf('/'))); }, StringComparer.OrdinalIgnoreCase) .ToDictionary(group => group.Key, group => group.ToList()); var resolvedPackageReferences = msBuildCompiledProject.GetItems("Reference") .Where(reference => reference.GetMetadataValue("NuGetSourceType").Equals("Package", StringComparison.OrdinalIgnoreCase)); foreach (var resolvedPackageReference in resolvedPackageReferences) { var assemblyName = Path.GetFileNameWithoutExtension(resolvedPackageReference.EvaluatedInclude); // Add the assembly to the containing package and all parent packages. var seenParents = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var queue = new Queue <string>(); queue.Enqueue(resolvedPackageReference.GetMetadataValue("NuGetPackageId")); while (queue.Count > 0) { var packageId = queue.Dequeue(); if (!packageAssemblies.TryGetValue(packageId, out var assemblies)) { assemblies = new List <string>(); packageAssemblies.Add(packageId, assemblies); } assemblies.Add(assemblyName); if (packageParents.TryGetValue(packageId, out var parents)) { foreach (var parent in parents) { if (seenParents.Add(parent)) { queue.Enqueue(parent); } } } } } } return(new Project { AssemblyName = assembly.GetName().Name, AssemblyReferences = assemblyReferences, References = references, ProjectReferences = projectReferences, PackageReferences = packageReferences, PackageAssemblies = packageAssemblies, }); }
internal EnvironmentFactory(AnalyzerManager manager, ProjectFile projectFile) { _manager = manager; _projectFile = projectFile; }
private ProjectAnalyzer GetProjectAnalyzer(string projectFile, StringWriter log, AnalyzerManager manager = null) { // The path will get normalized inside the .GetProject() call below string projectPath = Path.GetFullPath( Path.Combine( Path.GetDirectoryName(typeof(ProjectAnalyzerExtensionsFixture).Assembly.Location), @"..\..\..\..\" + projectFile)); if (manager == null) { manager = new AnalyzerManager(new AnalyzerManagerOptions { LogWriter = log }); } return(manager.GetProject(projectPath)); }
private ProjectAnalyzer GetProjectAnalyzer(string projectFile, StringWriter log, AnalyzerManager manager = null) { string projectPath = Path.GetFullPath( Path.Combine( Path.GetDirectoryName(typeof(ProjectAnalyzerExtensionsFixture).Assembly.Location), @"..\..\..\..\" + projectFile)); if (manager == null) { manager = new AnalyzerManager(log); } return(manager.GetProject(projectPath.Replace('\\', Path.DirectorySeparatorChar))); }
internal override AnalyzerDriver AnalyzerForLanguage(ImmutableArray <DiagnosticAnalyzer> analyzers, AnalyzerManager analyzerManager) { throw new NotImplementedException(); }
internal int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsScriptRunner); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayVersion) { PrintVersion(consoleOutput); return(Succeeded); } if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (ReportErrors(Arguments.Errors, consoleOutput, errorLogger)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger, errorLogger); if (compilation == null) { return(Failed); } var diagnosticInfos = new List <DiagnosticInfo>(); ImmutableArray <DiagnosticAnalyzer> analyzers = ResolveAnalyzersFromArguments(diagnosticInfos, MessageProvider); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnosticInfos, MessageProvider, touchedFilesLogger); if (ReportErrors(diagnosticInfos, consoleOutput, errorLogger)) { return(Failed); } var diagnostics = new List <Diagnostic>(); ImmutableArray <EmbeddedText> embeddedTexts = AcquireEmbeddedTexts(compilation, diagnostics); if (ReportErrors(diagnostics, consoleOutput, errorLogger)) { return(Failed); } bool reportAnalyzer = false; CancellationTokenSource analyzerCts = null; AnalyzerManager analyzerManager = null; AnalyzerDriver analyzerDriver = null; try { // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (ReportErrors(compilation.GetParseDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } ConcurrentSet <Diagnostic> analyzerExceptionDiagnostics = null; if (!analyzers.IsEmpty) { analyzerCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); analyzerManager = new AnalyzerManager(); analyzerExceptionDiagnostics = new ConcurrentSet <Diagnostic>(); Action <Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); var analyzerOptions = new AnalyzerOptions(ImmutableArray <AdditionalText> .CastUp(additionalTextFiles)); analyzerDriver = AnalyzerDriver.CreateAndAttachToCompilation(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, Arguments.ReportAnalyzer, out compilation, analyzerCts.Token); reportAnalyzer = Arguments.ReportAnalyzer && !analyzers.IsEmpty; } if (ReportErrors(compilation.GetDeclarationDiagnostics(), consoleOutput, errorLogger)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); var finalPeFilePath = Path.Combine(Arguments.OutputDirectory, outputName); var finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalPeFilePath, ".pdb"); var finalXmlFilePath = Arguments.DocumentationPath; var diagnosticBag = DiagnosticBag.GetInstance(); Stream sourceLinkStreamOpt = null; try { // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); // The PDB path is emitted in it's entirety into the PE. This makes it impossible to have deterministic // builds that occur in different source directories. To enable this we shave all path information from // the PDB when specified by the user. // // This is a temporary work around to allow us to make progress with determinism. The following issue // tracks getting an official solution here. // // https://github.com/dotnet/roslyn/issues/9813 if (Arguments.ParseOptions.Features.ContainsKey("pdb-path-determinism") && !string.IsNullOrEmpty(emitOptions.PdbFilePath)) { emitOptions = emitOptions.WithPdbFilePath(Path.GetFileName(emitOptions.PdbFilePath)); } if (Arguments.SourceLink != null) { sourceLinkStreamOpt = OpenFile(Arguments.SourceLink, consoleOutput, FileMode.Open, FileAccess.Read, FileShare.Read); } var moduleBeingBuilt = compilation.CheckOptionsAndCreateModuleBuilder( diagnosticBag, Arguments.ManifestResources, emitOptions, debugEntryPoint: null, sourceLinkStream: sourceLinkStreamOpt, embeddedTexts: embeddedTexts, testData: null, cancellationToken: cancellationToken); if (moduleBeingBuilt != null) { bool success; try { success = compilation.CompileMethods( moduleBeingBuilt, Arguments.EmitPdb, diagnosticBag, filterOpt: null, cancellationToken: cancellationToken); if (success) { // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists Stream xmlStreamOpt = null; if (finalXmlFilePath != null) { xmlStreamOpt = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xmlStreamOpt == null) { return(Failed); } xmlStreamOpt.SetLength(0); } using (xmlStreamOpt) { IEnumerable <DiagnosticInfo> errors; using (var win32ResourceStreamOpt = GetWin32Resources(Arguments, compilation, out errors)) { if (ReportErrors(errors, consoleOutput, errorLogger)) { return(Failed); } success = compilation.GenerateResourcesAndDocumentationComments( moduleBeingBuilt, xmlStreamOpt, win32ResourceStreamOpt, diagnosticBag, cancellationToken); } // only report unused usings if we have success. if (success) { compilation.ReportUnusedImports(null, diagnosticBag, cancellationToken); } } } compilation.CompleteTrees(null); if (analyzerDriver != null) { // GetDiagnosticsAsync is called after ReportUnusedImports // since that method calls EventQueue.TryComplete. Without // TryComplete, we may miss diagnostics. var hostDiagnostics = analyzerDriver.GetDiagnosticsAsync(compilation).Result; diagnosticBag.AddRange(hostDiagnostics); if (hostDiagnostics.Any(IsReportedError)) { success = false; } } } finally { moduleBeingBuilt.CompilationFinished(); } if (success) { bool emitPdbFile = Arguments.EmitPdb && emitOptions.DebugInformationFormat != Emit.DebugInformationFormat.Embedded; using (var peStreamProvider = new CompilerEmitStreamProvider(this, finalPeFilePath)) using (var pdbStreamProviderOpt = emitPdbFile ? new CompilerEmitStreamProvider(this, finalPdbFilePath) : null) { success = compilation.SerializeToPeStream( moduleBeingBuilt, peStreamProvider, pdbStreamProviderOpt, testSymWriterFactory: null, diagnostics: diagnosticBag, metadataOnly: emitOptions.EmitMetadataOnly, cancellationToken: cancellationToken); if (success && touchedFilesLogger != null) { if (pdbStreamProviderOpt != null) { touchedFilesLogger.AddWritten(finalPdbFilePath); } touchedFilesLogger.AddWritten(finalPeFilePath); } } } } var compileAndEmitDiagnostics = diagnosticBag.ToReadOnly(); if (ReportErrors(compileAndEmitDiagnostics, consoleOutput, errorLogger)) { return(Failed); } } finally { diagnosticBag.Free(); sourceLinkStreamOpt?.Dispose(); } cancellationToken.ThrowIfCancellationRequested(); if (analyzerExceptionDiagnostics != null && ReportErrors(analyzerExceptionDiagnostics, consoleOutput, errorLogger)) { return(Failed); } bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (ReportErrors(additionalFile.Diagnostics, consoleOutput, errorLogger)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, mode: FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, mode: FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } } finally { // At this point analyzers are already complete in which case this is a no-op. Or they are // still running because the compilation failed before all of the compilation events were // raised. In the latter case the driver, and all its associated state, will be waiting around // for events that are never coming. Cancel now and let the clean up process begin. if (analyzerCts != null) { analyzerCts.Cancel(); if (analyzerManager != null) { // Clear cached analyzer descriptors and unregister exception handlers hooked up to the LocalizableString fields of the associated descriptors. analyzerManager.ClearAnalyzerState(analyzers); } if (reportAnalyzer) { ReportAnalyzerExecutionTime(consoleOutput, analyzerDriver, Culture, compilation.Options.ConcurrentBuild); } } } return(Succeeded); }
private Project Analyze(AnalyzerManager manager, string path, string?tfm, Dictionary <string, Project> built) { if (manager == null) { throw new ArgumentNullException(nameof(manager)); } if (built == null) { throw new ArgumentNullException(nameof(built)); } path = Path.GetFullPath(path); // Already built this project? if (built.TryGetValue(Path.GetFileName(path), out var project)) { return(project); } project = new Project(path); var result = Build(manager, project, tfm); if (result == null) { throw new InvalidOperationException($"Could not build {path}."); } // Get the asset path. var assetPath = result.GetProjectAssetsFilePath(); if (!File.Exists(assetPath)) { // Todo: Make sure this exists in future throw new InvalidOperationException($"{assetPath} not found. Please run 'dotnet restore'."); } // Set project information. project.TargetFramework = result.TargetFramework; project.LockFilePath = result.GetProjectAssetsFilePath(); // Add the project to the built list. built.Add(Path.GetFileName(path), project); // Get the package references. foreach (var packageReference in result.PackageReferences) { if (packageReference.Value.TryGetValue("Version", out var version)) { project.Packages.Add(new Package(packageReference.Key, version)); } } // Analyze all project references. foreach (var projectReference in result.ProjectReferences) { var projectReferencePath = PathUtility.GetPathRelativeToProject(project, projectReference); var analyzedProjectReference = Analyze(manager, projectReferencePath, project.TargetFramework, built); project.ProjectReferences.Add(analyzedProjectReference); } return(project); }
public void AddProject(string projectPath) { var projectAnalyzer = AnalyzerManager.GetProject(projectPath); projectAnalyzer.AddToWorkspace(Workspace, addProjectReferences: true); }
public async Task <int> InvokeAsync(InvocationContext context) { var migration = string.Join(" ", context.ParseResult .FindResultFor(MigrationArgument) .Tokens .Select(x => x.Value)); var solutionPath = string.Join(" ", context.ParseResult .FindResultFor(SolutionArgument) .Tokens .Select(x => x.Value)); var manager = new AnalyzerManager(solutionPath);; foreach (var project in manager.Projects) { var results = project.Value.Build(); foreach (var result in results) { if (!bool.TryParse( result.GetProperty("IsDatabaseProvider"), out var isDatabaseProvider)) { continue; } if (!bool.TryParse( result.GetProperty("DatabaseSupportsMigration"), out var databaseSupportsMigration)) { continue; } if (!(isDatabaseProvider && databaseSupportsMigration)) { continue; } var objFolder = result.GetProperty( "BaseIntermediateOutputPath"); var assemblyName = result.GetProperty("AssemblyName"); var args = $"ef migrations add {migration} " + $"-p {result.ProjectFilePath} " + $"--msbuildprojectextensionspath {objFolder} " + "--json --prefix-output --no-color"; using var process = Process.StartProcess( "dotnet", args, workingDir: Path.GetDirectoryName( result.ProjectFilePath), stdOut: x => ProcessStdout(x), stdErr: x => Console.WriteLine(x)); var dotnetEfResult = await process.CompleteAsync(); if (dotnetEfResult != 0) { return(dotnetEfResult); } } } Console.WriteLine("OK"); return(0);
private int RunCore(TextWriter consoleOutput, CancellationToken cancellationToken) { Debug.Assert(!Arguments.IsInteractive); cancellationToken.ThrowIfCancellationRequested(); if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); } if (Arguments.DisplayHelp) { PrintHelp(consoleOutput); return(Succeeded); } if (PrintErrors(Arguments.Errors, consoleOutput)) { return(Failed); } var touchedFilesLogger = (Arguments.TouchedFilesPath != null) ? new TouchedFileLogger() : null; Compilation compilation = CreateCompilation(consoleOutput, touchedFilesLogger); if (compilation == null) { return(Failed); } var diagnostics = new List <DiagnosticInfo>(); var analyzers = ResolveAnalyzersFromArguments(diagnostics, MessageProvider, touchedFilesLogger); var additionalTextFiles = ResolveAdditionalFilesFromArguments(diagnostics, MessageProvider, touchedFilesLogger); if (PrintErrors(diagnostics, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); var analyzerOptions = new AnalyzerOptions(ImmutableArray.Create <AdditionalText, AdditionalTextFile>(additionalTextFiles)); AnalyzerDriver analyzerDriver = null; AnalyzerManager analyzerManager = null; ConcurrentSet <Diagnostic> analyzerExceptionDiagnostics = null; if (!analyzers.IsDefaultOrEmpty) { analyzerManager = new AnalyzerManager(); analyzerExceptionDiagnostics = new ConcurrentSet <Diagnostic>(); Action <Diagnostic> addExceptionDiagnostic = diagnostic => analyzerExceptionDiagnostics.Add(diagnostic); analyzerDriver = AnalyzerDriver.Create(compilation, analyzers, analyzerOptions, analyzerManager, addExceptionDiagnostic, out compilation, cancellationToken); } // Print the diagnostics produced during the parsing stage and exit if there were any errors. if (PrintErrors(compilation.GetParseDiagnostics(), consoleOutput)) { return(Failed); } if (PrintErrors(compilation.GetDeclarationDiagnostics(), consoleOutput)) { return(Failed); } EmitResult emitResult; // EDMAURER: Don't yet know if there are method body errors. don't overwrite // any existing output files until the compilation is known to be successful. string tempExeFilename = null; string tempPdbFilename = null; // NOTE: as native compiler does, we generate the documentation file // NOTE: 'in place', replacing the contents of the file if it exists try { FileStream output = CreateTempFile(consoleOutput, out tempExeFilename); // Can happen when temp directory is "full" if (output == null) { return(Failed); } string finalOutputPath; string finalPdbFilePath; string finalXmlFilePath; using (output) { FileStream pdb = null; FileStream xml = null; cancellationToken.ThrowIfCancellationRequested(); if (Arguments.EmitPdb) { pdb = CreateTempFile(consoleOutput, out tempPdbFilename); if (pdb == null) { return(Failed); } } cancellationToken.ThrowIfCancellationRequested(); finalXmlFilePath = Arguments.DocumentationPath; if (finalXmlFilePath != null) { xml = OpenFile(finalXmlFilePath, consoleOutput, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete); if (xml == null) { return(Failed); } xml.SetLength(0); } cancellationToken.ThrowIfCancellationRequested(); IEnumerable <DiagnosticInfo> errors; using (var win32Res = GetWin32Resources(Arguments, compilation, out errors)) using (pdb) using (xml) { if (PrintErrors(errors, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); string outputName = GetOutputFileName(compilation, cancellationToken); finalOutputPath = Path.Combine(Arguments.OutputDirectory, outputName); finalPdbFilePath = Arguments.PdbPath ?? Path.ChangeExtension(finalOutputPath, ".pdb"); // NOTE: Unlike the PDB path, the XML doc path is not embedded in the assembly, so we don't need to pass it to emit. var emitOptions = Arguments.EmitOptions. WithOutputNameOverride(outputName). WithPdbFilePath(finalPdbFilePath); emitResult = compilation.Emit(output, pdb, xml, win32Res, Arguments.ManifestResources, emitOptions, cancellationToken); } } GenerateSqmData(Arguments.CompilationOptions, emitResult.Diagnostics); if (PrintErrors(emitResult.Diagnostics, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (analyzerDriver != null) { var analyzerDiagnostics = analyzerDriver.GetDiagnosticsAsync().Result; var allAnalyzerDiagnostics = analyzerDiagnostics.AddRange(analyzerExceptionDiagnostics); if (PrintErrors(allAnalyzerDiagnostics, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); } bool errorsReadingAdditionalFiles = false; foreach (var additionalFile in additionalTextFiles) { if (PrintErrors(additionalFile.Diagnostics, consoleOutput)) { errorsReadingAdditionalFiles = true; } } if (errorsReadingAdditionalFiles) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (!TryDeleteFile(finalOutputPath, consoleOutput) || !TryMoveFile(tempExeFilename, finalOutputPath, consoleOutput)) { return(Failed); } cancellationToken.ThrowIfCancellationRequested(); if (tempPdbFilename != null) { if (!TryDeleteFile(finalPdbFilePath, consoleOutput) || !TryMoveFile(tempPdbFilename, finalPdbFilePath, consoleOutput)) { return(Failed); } } cancellationToken.ThrowIfCancellationRequested(); if (Arguments.TouchedFilesPath != null) { Debug.Assert(touchedFilesLogger != null); touchedFilesLogger.AddWritten(tempExeFilename); touchedFilesLogger.AddWritten(finalOutputPath); if (tempPdbFilename != null) { touchedFilesLogger.AddWritten(tempPdbFilename); touchedFilesLogger.AddWritten(finalPdbFilePath); } if (finalXmlFilePath != null) { touchedFilesLogger.AddWritten(finalXmlFilePath); } var readStream = OpenFile(Arguments.TouchedFilesPath + ".read", consoleOutput, FileMode.OpenOrCreate); if (readStream == null) { return(Failed); } using (var writer = new StreamWriter(readStream)) { touchedFilesLogger.WriteReadPaths(writer); } var writtenStream = OpenFile(Arguments.TouchedFilesPath + ".write", consoleOutput, FileMode.OpenOrCreate); if (writtenStream == null) { return(Failed); } using (var writer = new StreamWriter(writtenStream)) { touchedFilesLogger.WriteWrittenPaths(writer); } } return(Succeeded); } finally { if (tempExeFilename != null) { TryDeleteFile(tempExeFilename, consoleOutput: null); } if (tempPdbFilename != null) { TryDeleteFile(tempPdbFilename, consoleOutput: null); } } }
public List <ClassFileInfo> Deep() { List <ClassFileInfo> result = new List <ClassFileInfo>(); var solutionFilePath = BuildWorkspaceHelper.GetRelativeWorkspacePath("Syinpo.Model\\Syinpo.Model.csproj"); { //using( var work = MSBuildWorkspace.Create() ) { // var project = work.OpenProjectAsync( solutionFilePath ).Result; // var documents = project.Documents.Where( w => w.Name.EndsWith( ".cs" ) ).ToList(); //} } AnalyzerManager manager = new AnalyzerManager(); var analyzer = manager.GetProject(solutionFilePath); AdhocWorkspace workspace = analyzer.GetWorkspace(); var project = workspace.CurrentSolution.Projects.First(); var documents = project.Documents.Where(w => w.Name.EndsWith(".cs")).ToList(); foreach (var document in documents) { string fileName = document.Name; string filePath = document.FilePath; var classes = document.GetSyntaxRootAsync().Result.DescendantNodes().OfType <ClassDeclarationSyntax>(); var classes2 = document.GetSyntaxRootAsync().Result.DescendantNodes().ToList().OfType <EnumDeclarationSyntax>(); if (classes.Any()) { foreach (var cl in classes) { NamespaceDeclarationSyntax namespaceDeclarationSyntax = null; if (!SyntaxNodeHelper.TryGetParentSyntax(cl, out namespaceDeclarationSyntax)) { continue; } var namespaceName = namespaceDeclarationSyntax.Name.ToString(); var fullClassName = namespaceName + "." + cl.Identifier.ToString(); var keys = document.Folders.ToList(); keys.Add(fileName); result.Add(new ClassFileInfo { FileName = fileName, FilePath = filePath, ClassName = cl.Identifier.ToString(), FullClassName = fullClassName, Key = string.Join(@"/", keys.ToArray()) }); } } if (classes2.Any()) { foreach (var cl in classes2) { NamespaceDeclarationSyntax namespaceDeclarationSyntax = null; if (!SyntaxNodeHelper.TryGetParentSyntax(cl, out namespaceDeclarationSyntax)) { continue; } var namespaceName = namespaceDeclarationSyntax.Name.ToString(); var fullClassName = namespaceName + "." + cl.Identifier.ToString(); var keys = document.Folders.ToList(); keys.Add(fileName); result.Add(new ClassFileInfo { FileName = fileName, FilePath = filePath, ClassName = cl.Identifier.ToString(), FullClassName = fullClassName, Key = string.Join(@"/", keys.ToArray()) }); } } #region Old if (false) { SourceText text = document.GetTextAsync().Result; var span = TextSpan.FromBounds(0, text.Length); IEnumerable <ClassifiedSpan> classifiedSpans = null; try { classifiedSpans = Classifier.GetClassifiedSpansAsync(document, span).Result; IEnumerable <Range> ranges = classifiedSpans.Select(classifiedSpan => new Range(classifiedSpan, text.GetSubText(classifiedSpan.TextSpan).ToString())); // var classes = ranges.Where(w => w.ClassificationType == "class name").ToList(); } catch (Exception ex) { throw new Exception("Exception during Classification of document: " + document.FilePath); } } #endregion } return(result); }
internal EnvironmentFactory(AnalyzerManager manager, ProjectFile projectFile) { _manager = manager; _projectFile = projectFile; _logger = _manager.LoggerFactory?.CreateLogger <EnvironmentFactory>(); }
public DependencyGraph Analyze(string projectPath, string framework = null) { if (string.IsNullOrWhiteSpace(projectPath)) { throw new ArgumentException(nameof(projectPath)); } if (!File.Exists(projectPath)) { throw new ArgumentException("Project path does not exist.", nameof(projectPath)); } var analyzerManager = new AnalyzerManager(new AnalyzerManagerOptions { LoggerFactory = _loggerFactory }); var projectAnalyzer = analyzerManager.GetProject(projectPath); var analyzeResult = string.IsNullOrEmpty(framework) ? projectAnalyzer.Build() : projectAnalyzer.Build(framework); var projectInstance = analyzeResult.ProjectInstance; if (projectInstance == null) { // Todo: Something went wrong, log and return better exception. throw new InvalidOperationException("Unable to load project."); } if (!projectInstance.IsNetSdkProject()) { // Todo: Support "legacy" projects in the future. throw new InvalidOperationException("Unable to load project."); } var projectAssetsFilePath = projectInstance.GetProjectAssetsFilePath(); if (!File.Exists(projectAssetsFilePath)) { // Todo: Make sure this exists in future throw new InvalidOperationException($"{projectAssetsFilePath} not found. Please run 'dotnet restore'"); } var lockFile = new LockFileFormat().Read(projectAssetsFilePath); var targetFramework = analyzeResult.GetTargetFramework(); var libraries = lockFile.Targets.Single(x => x.TargetFramework == targetFramework) .Libraries.Where(x => x.IsPackage()).ToList(); var projectNode = new ProjectReferenceNode(projectPath); var builder = new DependencyGraph.Builder(projectNode); var libraryNodes = new Dictionary <string, PackageReferenceNode>(StringComparer.OrdinalIgnoreCase); foreach (var library in libraries) { var libraryNode = library.ToNode(); builder.WithNode(libraryNode); libraryNodes.Add(libraryNode.PackageId, libraryNode); if (library.FrameworkAssemblies.Count > 0) { var assemblyNodes = library.FrameworkAssemblies .Select(x => new AssemblyReferenceNode(x)); builder.WithNodes(assemblyNodes); builder.WithEdges(assemblyNodes .Select(x => new Edge(libraryNode, x))); } if (library.RuntimeAssemblies.Count > 0) { var assemblyNodes = library.RuntimeAssemblies .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.Path))) .Where(x => x.Id != "_._"); if (assemblyNodes.Any()) { builder.WithNodes(assemblyNodes); builder.WithEdges(assemblyNodes .Select(x => new Edge(libraryNode, x))); } } //if (library.CompileTimeAssemblies.Count > 0) //{ // var assemblyNodes = library.CompileTimeAssemblies // .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.Path))); // builder.WithNodes(assemblyNodes); // builder.WithEdges(assemblyNodes // .Select(x => new Edge(libraryNode, x))); //} } foreach (var library in libraries) { var libraryNode = library.ToNode(); if (library.Dependencies.Count > 0) { builder.WithEdges(library.Dependencies .Select(x => new Edge(libraryNode, libraryNodes[x.Id], x.VersionRange.ToString()))); } } builder.WithEdges(projectInstance.GetItems("PackageReference") .Select(x => new Edge(projectNode, libraryNodes[x.EvaluatedInclude], x.GetMetadataValue("Version")))); var references = projectInstance.GetItems("Reference") .Select(x => new AssemblyReferenceNode(Path.GetFileName(x.EvaluatedInclude))); builder.WithNodes(references); builder.WithEdges(references.Select(x => new Edge(projectNode, x))); return(builder.Build()); }
public static async Task <Compilation> GetCompilationFromProject(string csprojPath, int verbosityLevel, Dictionary <string, string> additionalProperties, IEnumerable <string> conditionalSymbols) { conditionalSymbols = conditionalSymbols != null? conditionalSymbols.Where(x => !string.IsNullOrEmpty(x)).ToArray() : Enumerable.Empty <string>(); // f*****g workaround of resolve reference... var externalReferences = new List <PortableExecutableReference>(); { var locations = new List <string>(); locations.Add(typeof(object).Assembly.Location); // mscorlib locations.Add(typeof(System.Linq.Enumerable).Assembly.Location); // core var xElem = XElement.Load(csprojPath); var ns = xElem.Name.Namespace; var csProjRoot = Path.GetDirectoryName(csprojPath); var framworkRoot = Path.GetDirectoryName(typeof(object).Assembly.Location); foreach (var item in xElem.Descendants(ns + "Reference")) { var hintPath = item.Element(ns + "HintPath")?.Value; if (hintPath == null) { var path = Path.Combine(framworkRoot, item.Attribute("Include").Value + ".dll"); locations.Add(path); } else { locations.Add(Path.Combine(csProjRoot, hintPath)); } } foreach (var item in locations.Distinct()) { if (File.Exists(item)) { externalReferences.Add(MetadataReference.CreateFromFile(item)); } } } EnvironmentHelper.Setup(); var analyzerOptions = new AnalyzerManagerOptions(); if (verbosityLevel > 0) { analyzerOptions.LogWriter = Console.Out; } var manager = new AnalyzerManager(analyzerOptions); var projectAnalyzer = manager.GetProject(csprojPath); projectAnalyzer.AddBuildLogger(new Microsoft.Build.Logging.ConsoleLogger(verbosityLevel.ToLoggerVerbosity())); var buildopts = new EnvironmentOptions(); if (additionalProperties != null) { foreach (var kv in additionalProperties) { buildopts.GlobalProperties[kv.Key] = kv.Value; projectAnalyzer.SetGlobalProperty(kv.Key, kv.Value); } } if (conditionalSymbols.Any()) { buildopts.GlobalProperties["DefineConstants"] = string.Join("%3b", conditionalSymbols); } var analyzerResults = projectAnalyzer.Build(buildopts); var analyzerResult = analyzerResults.FirstOrDefault(x => x.Succeeded); if (analyzerResult == null) { throw new Exception("no succeeded analyzer result found"); } var ws = new AdhocWorkspace(); var project = analyzerResult.AddToWorkspace(ws); var parseopts = project.ParseOptions as CSharpParseOptions; if (parseopts != null) { var symbols = analyzerResult.Properties.ContainsKey("DefineConstants") ? conditionalSymbols.Concat( analyzerResult.Properties["DefineConstants"].Split(';') ).OrderBy(x => x).Distinct() : conditionalSymbols ; project = project.WithParseOptions(parseopts.WithPreprocessorSymbols(symbols)); } var compilation = await project.GetCompilationAsync().ConfigureAwait(false); return(compilation); }
internal override AnalyzerDriver AnalyzerForLanguage(ImmutableArray <DiagnosticAnalyzer> analyzers, AnalyzerManager analyzerManager) { Func <SyntaxNode, int> getKind = node => node.RawKind; Func <SyntaxTrivia, bool> isComment = trivia => false; return(new AnalyzerDriver <int>(analyzers, getKind, analyzerManager, isComment)); }
ProjectAnalyzer(AnalyzerManager manager) => _analyzers = manager.Projects.Select(x => x.Value).ToArray();
public static async Task <int> GoAsync(string[] args) { //.NET core csprojects are not supported all that well. // https://github.com/dotnet/roslyn/issues/21660 :sadpanda: // Use Buildalyzer to get a workspace from the solution. var options = new AnalyzerManagerOptions() { ProjectFilter = p => ProjectsWeWant.Contains(p.ProjectName) }; var analyzer = new AnalyzerManager(Path.Combine(Program.InputDirPath, "..", "Elasticsearch.sln"), options); var workspace = analyzer.GetWorkspace(); var seenFailures = false; workspace.WorkspaceFailed += (s, e) => { Console.Error.WriteLine($"Workplace failure: {e.Diagnostic.Message}"); seenFailures = true; }; var projects = workspace.CurrentSolution.Projects .ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase); if (seenFailures) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine("Documentation failed to generate."); Console.ResetColor(); return(2); } DeleteExistingTmpDocs(); foreach (var file in GetDocumentFiles(projects).SelectMany(s => s)) { await file.SaveToDocumentationFolderAsync(); } if (seenFailures) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine("Documentation failed to generate."); Console.ResetColor(); return(2); } CopyBreakingChangesDocs(); CopyReleaseNotes(); DeleteExistingDocsAndSwap(); Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Documentation generated."); Console.ResetColor(); if (Debugger.IsAttached) { Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } return(0); }
public Task <int> OnExecuteAsync(CommandLineApplication app, CancellationToken cancellationToken) { bool isMSBuildFile; var path = ProjectPath; if (path == null) { path = Directory.GetCurrentDirectory(); var projectFiles = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly) .Where(p => s_projectExtensionFilter.Contains(Path.GetExtension(p))) .Take(2) .ToArray(); if (projectFiles.Length == 1) { path = projectFiles[0]; isMSBuildFile = true; } else { isMSBuildFile = false; } } else { path = Path.GetFullPath(path); isMSBuildFile = !Directory.Exists(path); } IEnumerable <string> filePaths; if (isMSBuildFile) { var originalWorkingDirectory = Environment.CurrentDirectory; Environment.CurrentDirectory = Path.GetDirectoryName(path) !; try { // https://daveaglick.com/posts/running-a-design-time-build-with-msbuild-apis var analyzerManager = new AnalyzerManager(); var project = analyzerManager.GetProject(path); var environmentOptions = new EnvironmentOptions(); if (Configuration != null) { environmentOptions.GlobalProperties["Configuration"] = Configuration; } Array.ForEach(RemainingArguments, arg => environmentOptions.Arguments.Add(arg)); IAnalyzerResult?analyzerResult; if (TargetFramework != null) { var buildEnvironment = project.EnvironmentFactory.GetBuildEnvironment(TargetFramework, environmentOptions); var analyzerResults = project.Build(buildEnvironment); analyzerResult = analyzerResults?.FirstOrDefault(result => result.TargetFramework == TargetFramework); if (analyzerResult == null) { throw new CommandException($"Unable to load MSBuild file \"{path}\" using target framework '{TargetFramework}'."); } } else { var buildEnvironment = project.EnvironmentFactory.GetBuildEnvironment(environmentOptions); var analyzerResults = project.Build(buildEnvironment); analyzerResult = analyzerResults?.FirstOrDefault(); if (analyzerResult == null) { throw new CommandException($"Unable to load MSBuild file \"{path}\"."); } } var basePath = Path.GetDirectoryName(path) !; if (!analyzerResult.Items.TryGetValue("Compile", out var compileItems)) { compileItems = Array.Empty <ProjectItem>(); } if (!analyzerResult.Items.TryGetValue("Content", out var contentItems)) { contentItems = Array.Empty <ProjectItem>(); } var projectItems = compileItems.Where(projectItem => s_compileExtensionFilter.Contains(Path.GetExtension(projectItem.ItemSpec))) .Concat(contentItems.Where(projectItem => s_contentExtensionFilter.Contains(Path.GetExtension(projectItem.ItemSpec)))); if (!IncludeLinks) { projectItems = projectItems.Where(projectItem => !projectItem.Metadata.Keys.Contains("Link")); } filePaths = projectItems .Select(projectItem => Path.GetFullPath(Path.Combine(basePath, projectItem.ItemSpec))); } finally { Environment.CurrentDirectory = originalWorkingDirectory; } } else { filePaths = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) .Where(p => s_extensionFilter.Contains(Path.GetExtension(p))); } foreach (var filePath in filePaths) { _context.Console.WriteLine(filePath); } return(Task.FromResult(0)); }
internal bool IsNotConfigurable() { return(AnalyzerManager.HasNotConfigurableTag(this.CustomTags)); }
public async Task Execute() { if (this.SiteDb == null || this.TransferTask == null || string.IsNullOrEmpty(TransferTask.FullStartUrl)) { return; } var cookieContainer = new System.Net.CookieContainer(); TransferPage transpage = new TransferPage(); transpage.absoluteUrl = TransferTask.FullStartUrl; transpage.taskid = TransferTask.Id; var oldpage = SiteDb.TransferPages.Get(transpage.Id); if (oldpage == null || oldpage.PageId == default(Guid)) { var down = await DownloadHelper.DownloadUrlAsync(transpage.absoluteUrl, cookieContainer, "GET", null, null); if (down == null) { return; } string htmlsource = down.GetString(); var savepage = new Page(); string name = TransferTask.RelativeName; if (!string.IsNullOrWhiteSpace(name)) { if (name.EndsWith("\\")) { name = name.TrimEnd('\\'); } if (name.EndsWith("/")) { name = name.TrimEnd('/'); } name = System.IO.Path.GetFileNameWithoutExtension(name); } if (!string.IsNullOrWhiteSpace(name)) { savepage.Name = name; } htmlsource = UrlHelper.ReplaceMetaCharSet(htmlsource); string FirstImportUrl = SiteDb.TransferTasks.FirstImportHost(); if (string.IsNullOrEmpty(FirstImportUrl)) { FirstImportUrl = TransferTask.FullStartUrl; } DownloadManager manager = new DownloadManager() { SiteDb = SiteDb }; manager.OriginalImportUrl = FirstImportUrl; var context = AnalyzerManager.Execute(htmlsource, transpage.absoluteUrl, savepage.Id, savepage.ConstType, manager, FirstImportUrl); htmlsource = context.HtmlSource; savepage.Body = htmlsource; string PageRelativeName = TransferTask.RelativeName; if (string.IsNullOrWhiteSpace(PageRelativeName)) { bool issamehost = Kooboo.Lib.Helper.UrlHelper.isSameHost(TransferTask.FullStartUrl, FirstImportUrl); PageRelativeName = UrlHelper.RelativePath(TransferTask.FullStartUrl, issamehost); } if (!PageRelativeName.StartsWith("/")) { PageRelativeName = "/" + PageRelativeName; } SiteDb.Routes.AddOrUpdate(PageRelativeName, savepage.ConstType, savepage.Id, this.TransferTask.UserId); SiteDb.Pages.AddOrUpdate(savepage, this.TransferTask.UserId); while (!manager.IsComplete) { System.Threading.Thread.Sleep(15); } transpage.done = true; transpage.PageId = savepage.Id; SiteDb.TransferPages.AddOrUpdate(transpage); } this.SiteDb.TransferTasks.SetDone(this.TransferTask.Id); }
private static void Run(Options options) { if (options.Debug) { Console.WriteLine($"Waiting for a debugger to attach (PID {Process.GetCurrentProcess().Id})"); while (!Debugger.IsAttached) { Thread.Sleep(1000); } Debugger.Break(); } // MsBuild will end up using the current working directory at time, so set it to the root. if (!string.IsNullOrEmpty(options.Root)) { Directory.SetCurrentDirectory(options.Root); } var projectFiles = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.*proj", SearchOption.AllDirectories); var manager = new AnalyzerManager(); var projects = new Dictionary <string, Project>(); foreach (var projectFile in projectFiles) { var project = Project.GetProject(manager, options, projectFile); if (project == null) { continue; } foreach (var reference in project.References) { if (!project.AssemblyReferences.Contains(reference)) { Console.WriteLine($"Reference {reference} can be removed from {projectFile}"); } } foreach (var projectReference in project.ProjectReferences) { var projectReferenceAssemblyName = projectReference.AssemblyName; if (!project.AssemblyReferences.Contains(projectReferenceAssemblyName)) { Console.WriteLine($"ProjectReference {projectReference} can be removed from {projectFile}"); } } foreach (var packageReference in project.PackageReferences) { if (!project.PackageAssemblies.TryGetValue(packageReference, out var packageAssemblies)) { // These are likely Analyzers, tools, etc. continue; } if (!packageAssemblies.Any(packageAssembly => project.AssemblyReferences.Contains(packageAssembly))) { Console.WriteLine($"PackageReference {packageReference} can be removed from {projectFile}"); } } } }
// WIP function for getting Roslyn's workspace from csproj public static async Task <AdhocWorkspace> GetWorkspaceWithPreventBuildEventAsync(this AnalyzerManager manager) { var projPath = manager.Projects.First().Value.ProjectFile.Path; var ws = new AdhocWorkspace(); foreach (var result in await GetAnalyzerResults(manager, projPath)) { // getting only successful build if (result.Succeeded) { result.AddToWorkspace(ws); } } return(ws); }
public async Task CompileAsync(Project project, MainWindow mainWindow) { IAnalyzerManager m = new AnalyzerManager(SolutionFilePath); // var analyzer = m.GetProject(project.FilePath); // var x = m.GetWorkspace(); // AdhocWorkspace workspace = analyzer.GetWorkspace(); foreach (var(key, value) in m.Projects) { Debug.WriteLine(key); } var p = m.Projects[project.FilePath]; var results = p.Build(); AdhocWorkspace w = null; foreach (var analyzerResult in results) { w = analyzerResult.GetWorkspace(); break; } mainWindow.Project = w.CurrentSolution.Projects.First(z => z.FilePath == project.FilePath); foreach (var mainWindowAnalyzerDll in mainWindow.AnalyzerDlls) { mainWindow.LoadAnalyzers(null, mainWindowAnalyzerDll); } var curProject = mainWindow.Project; // var w = // foreach (var action in curProject.SelectMany(z => z.CompilationStartActions)) // { // var ct = new MyComp(Compilation, // new AnalyzerOptions(ImmutableArray<AdditionalText>.Empty), CancellationToken.None); // action(ct); // } foreach (var projectAllProjectReference in curProject.AllProjectReferences) { Debug.WriteLine("Project reference " + projectAllProjectReference); } foreach (var r in curProject.MetadataReferences) { Debug.WriteLine("metadata reference " + r.Display); } if (curProject.AnalyzerReferences != null) { foreach (var projectAnalyzerReference in curProject.AnalyzerReferences) { Debug.WriteLine("analyzer reference " + projectAnalyzerReference.Display); } } var compilation = await curProject.GetCompilationAsync(); foreach (var diagnostic in compilation.GetDiagnostics()) { if (diagnostic.IsSuppressed) { continue; } if (diagnostic.Severity < DiagnosticSeverity.Error) { continue; } Debug.WriteLine("diag " + diagnostic.GetMessage()); } foreach (var diagnostic in compilation.GetDiagnostics()) { if (diagnostic.IsSuppressed) { continue; } if (diagnostic.Severity >= DiagnosticSeverity.Error) { continue; } if (diagnostic.Severity < DiagnosticSeverity.Info) { continue; } Debug.WriteLine("diag " + diagnostic.GetMessage()); } }
/// <summary> /// Returns true if diagnostic descriptor is a built-in compiler diagnostic or is not configurable. /// </summary> internal bool IsCompilerOrNotConfigurable() { return(AnalyzerManager.HasCompilerOrNotConfigurableTag(ImmutableCustomTags)); }
/// <summary> /// Point d'entrée. /// </summary> /// <param name="args"> /// Premier argument : chemin de la solution. /// Deuxième argument : racine de la SPA. /// Troisième argument : namespace du projet (exemple : "Kinetix"). /// </param> public static async Task Main(string[] args) { _solutionPath = args[0]; _serviceRoot = args[1]; _projectName = args[2]; _kinetix = args[3]; Solution solution = null; #if NET471 var msWorkspace = MSBuildWorkspace.Create(); msWorkspace.WorkspaceFailed += MsWorkspace_WorkspaceFailed; solution = await msWorkspace.OpenSolutionAsync(_solutionPath); #endif #if NETCOREAPP2_1 var adhocWorkspace = new AnalyzerManager(_solutionPath).GetWorkspace(); adhocWorkspace.WorkspaceFailed += AdhocWorkspace_WorkspaceFailed; solution = adhocWorkspace.CurrentSolution; // Weirdly, I have a lot of duplicate project references after loading a solution, so this is a quick hack to fix that. foreach (var project in solution.Projects) { solution = solution.WithProjectReferences(project.Id, project.ProjectReferences.Distinct()); } #endif // If path is not to services add "standard" path var outputPath = _serviceRoot.EndsWith("services") ? _serviceRoot : $"{_serviceRoot}/app/services"; var frontEnds = solution.Projects.Where(projet => projet.AssemblyName.StartsWith(_projectName) && projet.AssemblyName.EndsWith("FrontEnd")); var controllers = frontEnds.SelectMany(f => f.Documents).Where(document => document.Name.Contains("Controller") && !document.Folders.Contains("Transverse")); foreach (var controller in controllers) { var syntaxTree = await controller.GetSyntaxTreeAsync(); var controllerClass = GetClassDeclaration(syntaxTree); var model = await solution.GetDocument(syntaxTree).GetSemanticModelAsync(); var modelClass = model.GetDeclaredSymbol(controllerClass); // Skip if we extend a MVC controller if (_kinetix == "framework" && modelClass.BaseType.Name == "Controller") { continue; } IReadOnlyList <string> folders = null; #if NET471 folders = controller.Folders; #endif #if NETCOREAPP2_1 var parts = Path.GetRelativePath(controller.Project.FilePath, controller.FilePath).Split(@"\"); folders = parts.Skip(1).Take(parts.Length - 2).ToList(); #endif var firstFolder = frontEnds.Count() > 1 ? $"/{controller.Project.Name.Split('.')[1].ToDashCase()}" : string.Empty; var secondFolder = folders.Count > 1 ? $"/{string.Join("/", folders.Skip(1).Select(f => f.ToDashCase()))}" : string.Empty; var folderCount = (frontEnds.Count() > 1 ? 1 : 0) + folders.Count - 1; var controllerName = $"{firstFolder}{secondFolder}/{controllerClass.Identifier.ToString().Replace("Controller", string.Empty).ToDashCase()}.ts".Substring(1); Console.WriteLine($"Generating {controllerName}"); var methods = GetMethodDeclarations(controllerClass, model); // If controller is not a direct Controller extender, ie it extends a base class string aspControllerClass = _kinetix == "Core" ? "Controller" : "ApiController"; if (modelClass.BaseType.Name != aspControllerClass) { var baseClassSyntaxTree = modelClass.BaseType.DeclaringSyntaxReferences.First().SyntaxTree; methods = methods.Concat(GetMethodDeclarations( GetClassDeclaration(baseClassSyntaxTree), await solution.GetDocument(baseClassSyntaxTree).GetSemanticModelAsync())); } var serviceList = methods .Where(m => m.method.Modifiers.Any(mod => mod.IsKind(SyntaxKind.PublicKeyword))) .Select(GetService) .Where(s => s != null) .ToList(); var fileName = $"{outputPath}/{controllerName}"; var fileInfo = new FileInfo(fileName); var directoryInfo = fileInfo.Directory; if (!directoryInfo.Exists) { Directory.CreateDirectory(directoryInfo.FullName); } var template = new ServiceSpa { ProjectName = _projectName, FolderCount = folderCount, Services = serviceList }; var output = template.TransformText(); File.WriteAllText(fileName, output, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } }
public void Build() { var sb = new StringBuilder(); var writer = new StringWriter(sb); /* Uncomment the below code to debug issues with msbuild */ /*var writer = new StreamWriter(Console.OpenStandardOutput()); * writer.AutoFlush = true; * * Console.SetOut(writer); * Console.SetError(writer);*/ if (IsSolutionFile()) { Logger.LogInformation("Loading the Workspace (Solution): " + WorkspacePath); AnalyzerManager analyzerManager = new AnalyzerManager(WorkspacePath, new AnalyzerManagerOptions { LogWriter = writer }); Logger.LogInformation("Loading the Solution Done: " + WorkspacePath); // AnalyzerManager builds the projects based on their dependencies // After this, code does not depend on Buildalyzer BuildSolution(analyzerManager); } else { AnalyzerManager analyzerManager = new AnalyzerManager(new AnalyzerManagerOptions { LogWriter = writer }); var dict = new Dictionary <Guid, IAnalyzerResult>(); using (AdhocWorkspace workspace = new AdhocWorkspace()) { Queue <string> queue = new Queue <string>(); ISet <string> existing = new HashSet <string>(); queue.Enqueue(WorkspacePath); existing.Add(WorkspacePath); /* * We need to resolve all the project dependencies to avoid compilation errors. * If we have compilation errors, we might miss some of the semantic values. */ while (queue.Count > 0) { var path = queue.Dequeue(); Logger.LogInformation("Building: " + path); IProjectAnalyzer projectAnalyzer = analyzerManager.GetProject(path); IAnalyzerResults analyzerResults = projectAnalyzer.Build(GetEnvironmentOptions(projectAnalyzer.ProjectFile)); IAnalyzerResult analyzerResult = analyzerResults.First(); if (analyzerResult == null) { FailedProjects.Add(new ProjectAnalysisResult() { ProjectAnalyzer = projectAnalyzer }); } dict[analyzerResult.ProjectGuid] = analyzerResult; analyzerResult.AddToWorkspace(workspace); foreach (var pref in analyzerResult.ProjectReferences) { if (!existing.Contains(pref)) { existing.Add(pref); queue.Enqueue(pref); } } } foreach (var project in workspace.CurrentSolution.Projects) { try { var result = dict[project.Id.Id]; var projectAnalyzer = analyzerManager.Projects.Values.FirstOrDefault(p => p.ProjectGuid.Equals(project.Id.Id)); Projects.Add(new ProjectAnalysisResult() { Project = project, AnalyzerResult = result, ProjectAnalyzer = projectAnalyzer }); } catch (Exception ex) { Logger.LogDebug(ex.StackTrace); } } } } Logger.LogDebug(sb.ToString()); writer.Flush(); writer.Close(); ProcessLog(writer.ToString()); }