/// <summary> /// Creates an AnalyzerFileReference with the given <paramref name="fullPath"/> and <paramref name="assemblyLoader"/>. /// </summary> /// <param name="fullPath">Full path of the analyzer assembly.</param> /// <param name="assemblyLoader">Loader for obtaining the <see cref="Assembly"/> from the <paramref name="fullPath"/></param> public AnalyzerFileReference(string fullPath, IAnalyzerAssemblyLoader assemblyLoader) { CompilerPathUtilities.RequireAbsolutePath(fullPath, nameof(fullPath)); FullPath = fullPath; _assemblyLoader = assemblyLoader ?? throw new ArgumentNullException(nameof(assemblyLoader)); _diagnosticAnalyzers = new( this, typeof(DiagnosticAnalyzerAttribute), GetDiagnosticsAnalyzerSupportedLanguages, allowNetFramework : true ); _generators = new( this, typeof(GeneratorAttribute), GetGeneratorSupportedLanguages, allowNetFramework : false ); // Note this analyzer full path as a dependency location, so that the analyzer loader // can correctly load analyzer dependencies. assemblyLoader.AddDependencyLocation(fullPath); }
private static bool CheckCore( string baseDirectory, IEnumerable <CommandLineAnalyzerReference> analyzerReferences, IAnalyzerAssemblyLoader loader, ICompilerServerLogger?logger, [NotNullWhen(false)] out List <string>?errorMessages) { errorMessages = null; var resolvedPaths = new List <string>(); foreach (var analyzerReference in analyzerReferences) { string?resolvedPath = FileUtilities.ResolveRelativePath(analyzerReference.FilePath, basePath: null, baseDirectory: baseDirectory, searchPaths: SpecializedCollections.EmptyEnumerable <string>(), fileExists: File.Exists); if (resolvedPath != null) { resolvedPath = FileUtilities.TryNormalizeAbsolutePath(resolvedPath); if (resolvedPath != null) { resolvedPaths.Add(resolvedPath); } } // Don't worry about paths we can't resolve. The compiler will report an error for that later. } // Register analyzers and their dependencies upfront, // so that assembly references can be resolved: foreach (var resolvedPath in resolvedPaths) { loader.AddDependencyLocation(resolvedPath); } // Load all analyzer assemblies: var loadedAssemblies = new List <Assembly>(); foreach (var resolvedPath in resolvedPaths) { loadedAssemblies.Add(loader.LoadFromPath(resolvedPath)); } // Third, check that the MVIDs of the files on disk match the MVIDs of the loaded assemblies. for (int i = 0; i < resolvedPaths.Count; i++) { var resolvedPath = resolvedPaths[i]; var loadedAssembly = loadedAssemblies[i]; var resolvedPathMvid = AssemblyUtilities.ReadMvid(resolvedPath); var loadedAssemblyMvid = loadedAssembly.ManifestModule.ModuleVersionId; if (resolvedPathMvid != loadedAssemblyMvid) { var message = $"analyzer assembly '{resolvedPath}' has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssembly.FullName}' has MVID '{loadedAssemblyMvid}'"; errorMessages ??= new List <string>(); errorMessages.Add(message); } } return(errorMessages == null); }
private static IEnumerable <AnalyzerReference> ResolveAnalyzerReferencesForProject(ProjectFileInfo projectFileInfo, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { foreach (var analyzerAssemblyPath in projectFileInfo.Analyzers.Distinct()) { analyzerAssemblyLoader.AddDependencyLocation(analyzerAssemblyPath); } return(projectFileInfo.Analyzers.Select(analyzerCandicatePath => new AnalyzerFileReference(analyzerCandicatePath, analyzerAssemblyLoader))); }
/// <summary> /// Creates an AnalyzerFileReference with the given <paramref name="fullPath"/> and <paramref name="assemblyLoader"/>. /// </summary> /// <param name="fullPath">Full path of the analyzer assembly.</param> /// <param name="assemblyLoader">Loader for obtaining the <see cref="Assembly"/> from the <paramref name="fullPath"/></param> public AnalyzerFileReference(string fullPath, IAnalyzerAssemblyLoader assemblyLoader) { _fullPath = fullPath ?? throw new ArgumentNullException(nameof(fullPath)); _diagnosticAnalyzers = new Extensions <DiagnosticAnalyzer>(this, IsDiagnosticAnalyzerAttribute); _assemblyLoader = assemblyLoader ?? throw new ArgumentNullException(nameof(assemblyLoader)); // Note this analyzer full path as a dependency location, so that the analyzer loader // can correctly load analyzer dependencies. if (PathUtilities.IsAbsolute(fullPath)) { assemblyLoader.AddDependencyLocation(fullPath); } }
public AnalyzerFileReference(string fullPath, IAnalyzerAssemblyLoader assemblyLoader) { CompilerPathUtilities.RequireAbsolutePath(fullPath, nameof(fullPath)); FullPath = fullPath; _assemblyLoader = assemblyLoader ?? throw new ArgumentNullException(nameof(assemblyLoader)); _diagnosticAnalyzers = new Extensions <DiagnosticAnalyzer>(this, IsDiagnosticAnalyzerAttribute, GetDiagnosticsAnalyzerSupportedLanguages); _generators = new Extensions <ISourceGenerator>(this, IsGeneratorAttribute, GetGeneratorsSupportedLanguages); // Note this analyzer full path as a dependency location, so that the analyzer loader // can correctly load analyzer dependencies. assemblyLoader.AddDependencyLocation(fullPath); }
public static ImmutableArray <AnalyzerFileReference> ResolveAnalyzerReferencesForProject(this ProjectFileInfo projectFileInfo, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { if (!projectFileInfo.RunAnalyzers || !projectFileInfo.RunAnalyzersDuringLiveAnalysis) { return(ImmutableArray <AnalyzerFileReference> .Empty); } foreach (var analyzerAssemblyPath in projectFileInfo.Analyzers.Distinct()) { analyzerAssemblyLoader.AddDependencyLocation(analyzerAssemblyPath); } return(projectFileInfo.Analyzers.Select(analyzerCandicatePath => new AnalyzerFileReference(analyzerCandicatePath, analyzerAssemblyLoader)).ToImmutableArray()); }
internal ImmutableArray <DiagnosticAnalyzer> ResolveAnalyzersFromArguments( string language, List <DiagnosticInfo> diagnostics, CommonMessageProvider messageProvider, IAnalyzerAssemblyLoader analyzerLoader) { var analyzerBuilder = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>(); EventHandler <AnalyzerLoadFailureEventArgs> errorHandler = (o, e) => { var analyzerReference = o as AnalyzerFileReference; DiagnosticInfo diagnostic; switch (e.ErrorCode) { case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToLoadAnalyzer: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_UnableToLoadAnalyzer, analyzerReference.FullPath, e.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToCreateAnalyzer: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_AnalyzerCannotBeCreated, e.TypeName, analyzerReference.FullPath, e.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.NoAnalyzers: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_NoAnalyzerInAssembly, analyzerReference.FullPath); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.None: default: return; } // Filter this diagnostic based on the compilation options so that /nowarn and /warnaserror etc. take effect. diagnostic = messageProvider.FilterDiagnosticInfo(diagnostic, this.CompilationOptions); if (diagnostic != null) { diagnostics.Add(diagnostic); } }; var resolvedReferences = ArrayBuilder <AnalyzerFileReference> .GetInstance(); foreach (var reference in AnalyzerReferences) { var resolvedReference = ResolveAnalyzerReference(reference, analyzerLoader); if (resolvedReference != null) { resolvedReferences.Add(resolvedReference); // register the reference to the analyzer loader: analyzerLoader.AddDependencyLocation(resolvedReference.FullPath); } else { diagnostics.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_MetadataFileNotFound, reference.FilePath)); } } // All analyzer references are registered now, we can start loading them: foreach (var resolvedReference in resolvedReferences) { resolvedReference.AnalyzerLoadFailed += errorHandler; resolvedReference.AddAnalyzers(analyzerBuilder, language); resolvedReference.AnalyzerLoadFailed -= errorHandler; } resolvedReferences.Free(); return(analyzerBuilder.ToImmutable()); }
public void AddDependencyLocation(string fullPath) { _fallbackLoader.AddDependencyLocation(fullPath); }
internal ImmutableArray<DiagnosticAnalyzer> ResolveAnalyzersFromArguments( string language, List<DiagnosticInfo> diagnostics, CommonMessageProvider messageProvider, IAnalyzerAssemblyLoader analyzerLoader) { var analyzerBuilder = ImmutableArray.CreateBuilder<DiagnosticAnalyzer>(); EventHandler<AnalyzerLoadFailureEventArgs> errorHandler = (o, e) => { var analyzerReference = o as AnalyzerFileReference; DiagnosticInfo diagnostic; switch (e.ErrorCode) { case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToLoadAnalyzer: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_UnableToLoadAnalyzer, analyzerReference.FullPath, e.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToCreateAnalyzer: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_AnalyzerCannotBeCreated, e.TypeName, analyzerReference.FullPath, e.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.NoAnalyzers: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_NoAnalyzerInAssembly, analyzerReference.FullPath); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.None: default: return; } // Filter this diagnostic based on the compilation options so that /nowarn and /warnaserror etc. take effect. diagnostic = messageProvider.FilterDiagnosticInfo(diagnostic, this.CompilationOptions); if (diagnostic != null) { diagnostics.Add(diagnostic); } }; var resolvedReferences = ArrayBuilder<AnalyzerFileReference>.GetInstance(); foreach (var reference in AnalyzerReferences) { var resolvedReference = ResolveAnalyzerReference(reference, analyzerLoader); if (resolvedReference != null) { resolvedReferences.Add(resolvedReference); // register the reference to the analyzer loader: analyzerLoader.AddDependencyLocation(resolvedReference.FullPath); } else { diagnostics.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_MetadataFileNotFound, reference.FilePath)); } } // All analyzer references are registered now, we can start loading them: foreach (var resolvedReference in resolvedReferences) { resolvedReference.AnalyzerLoadFailed += errorHandler; resolvedReference.AddAnalyzers(analyzerBuilder, language); resolvedReference.AnalyzerLoadFailed -= errorHandler; } resolvedReferences.Free(); return analyzerBuilder.ToImmutable(); }
private static bool CheckCore(string baseDirectory, IEnumerable <CommandLineAnalyzerReference> analyzerReferences, IAnalyzerAssemblyLoader loader, IEnumerable <string> ignorableReferenceNames) { var resolvedPaths = new List <string>(); foreach (var analyzerReference in analyzerReferences) { string resolvedPath = FileUtilities.ResolveRelativePath(analyzerReference.FilePath, basePath: null, baseDirectory: baseDirectory, searchPaths: SpecializedCollections.EmptyEnumerable <string>(), fileExists: File.Exists); if (resolvedPath != null) { resolvedPath = FileUtilities.TryNormalizeAbsolutePath(resolvedPath); if (resolvedPath != null) { resolvedPaths.Add(resolvedPath); } } // Don't worry about paths we can't resolve. The compiler will report an error for that later. } // First, check that the set of references is complete, modulo items in the safe list. foreach (var resolvedPath in resolvedPaths) { var missingDependencies = AssemblyUtilities.IdentifyMissingDependencies(resolvedPath, resolvedPaths); foreach (var missingDependency in missingDependencies) { if (!ignorableReferenceNames.Any(name => missingDependency.Name.StartsWith(name))) { CompilerServerLogger.Log($"Analyzer assembly {resolvedPath} depends on '{missingDependency}' but it was not found."); return(false); } } } // Register analyzers and their dependencies upfront, // so that assembly references can be resolved: foreach (var resolvedPath in resolvedPaths) { loader.AddDependencyLocation(resolvedPath); } // Load all analyzer assemblies: var loadedAssemblies = new List <Assembly>(); foreach (var resolvedPath in resolvedPaths) { loadedAssemblies.Add(loader.LoadFromPath(resolvedPath)); } // Third, check that the MVIDs of the files on disk match the MVIDs of the loaded assemblies. for (int i = 0; i < resolvedPaths.Count; i++) { var resolvedPath = resolvedPaths[i]; var loadedAssembly = loadedAssemblies[i]; var resolvedPathMvid = AssemblyUtilities.ReadMvid(resolvedPath); var loadedAssemblyMvid = loadedAssembly.ManifestModule.ModuleVersionId; if (resolvedPathMvid != loadedAssemblyMvid) { CompilerServerLogger.Log($"Analyzer assembly {resolvedPath} has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssembly.FullName}' has MVID '{loadedAssemblyMvid}'."); return(false); } } return(true); }
private static bool CheckCore(string baseDirectory, IEnumerable<CommandLineAnalyzerReference> analyzerReferences, IAnalyzerAssemblyLoader loader, IEnumerable<string> ignorableReferenceNames) { var resolvedPaths = new List<string>(); foreach (var analyzerReference in analyzerReferences) { string resolvedPath = FileUtilities.ResolveRelativePath(analyzerReference.FilePath, basePath: null, baseDirectory: baseDirectory, searchPaths: SpecializedCollections.EmptyEnumerable<string>(), fileExists: File.Exists); if (File.Exists(resolvedPath)) { resolvedPath = FileUtilities.TryNormalizeAbsolutePath(resolvedPath); if (resolvedPath != null) { resolvedPaths.Add(resolvedPath); } } // Don't worry about paths we can't resolve. The compiler will report an error for that later. } // First, check that the set of references is complete, modulo items in the safe list. foreach (var resolvedPath in resolvedPaths) { var missingDependencies = AssemblyUtilities.IdentifyMissingDependencies(resolvedPath, resolvedPaths); foreach (var missingDependency in missingDependencies) { if (!ignorableReferenceNames.Any(name => missingDependency.Name.StartsWith(name))) { CompilerServerLogger.Log($"Analyzer assembly {resolvedPath} depends on '{missingDependency}' but it was not found."); return false; } } } // Second, load all of the assemblies upfront. foreach (var resolvedPath in resolvedPaths) { loader.AddDependencyLocation(resolvedPath); } var loadedAssemblies = new List<Assembly>(); foreach (var resolvedPath in resolvedPaths) { loadedAssemblies.Add(loader.LoadFromPath(resolvedPath)); } // Third, check that the MVIDs of the files on disk match the MVIDs of the loaded assemblies. for (int i = 0; i < resolvedPaths.Count; i++) { var resolvedPath = resolvedPaths[i]; var loadedAssembly = loadedAssemblies[i]; var resolvedPathMvid = AssemblyUtilities.ReadMvid(resolvedPath); var loadedAssemblyMvid = loadedAssembly.ManifestModule.ModuleVersionId; if (resolvedPathMvid != loadedAssemblyMvid) { CompilerServerLogger.Log($"Analyzer assembly {resolvedPath} has MVID '{resolvedPathMvid}' but loaded assembly '{loadedAssembly.FullName}' has MVID '{loadedAssemblyMvid}'."); return false; } } return true; }
public void AddDependencyLocation(string fullPath) => _desktopLoader.AddDependencyLocation(ResolvePath(fullPath));
private void GetReferences(VisualBasicProjectFileLoader.VisualBasicProjectFile.VisualBasicCompilerInputs compilerInputs, ProjectInstance executedProject, ref IEnumerable <MetadataReference> metadataReferences, ref IEnumerable <AnalyzerReference> analyzerReferences) { // use command line parser to compute references using common logic List <string> list = new List <string>(); if (compilerInputs.LibPaths != null && compilerInputs.LibPaths.Count <string>() > 0) { list.Add("/libpath:\"" + string.Join(";", compilerInputs.LibPaths) + "\""); } // metadata references foreach (var current in compilerInputs.References) { string documentFilePath = base.GetDocumentFilePath(current); list.Add("/r:\"" + documentFilePath + "\""); } // analyzer references foreach (var current in compilerInputs.AnalyzerReferences) { string documentFilePath2 = base.GetDocumentFilePath(current); list.Add("/a:\"" + documentFilePath2 + "\""); } if (compilerInputs.NoStandardLib) { list.Add("/nostdlib"); } if (!string.IsNullOrEmpty(compilerInputs.VbRuntime)) { if (compilerInputs.VbRuntime == "Default") { list.Add("/vbruntime+"); } else if (compilerInputs.VbRuntime == "Embed") { list.Add("/vbruntime*"); } else if (compilerInputs.VbRuntime == "None") { list.Add("/vbruntime-"); } else { list.Add("/vbruntime: " + compilerInputs.VbRuntime); } } if (!string.IsNullOrEmpty(compilerInputs.SdkPath)) { list.Add("/sdkpath:" + compilerInputs.SdkPath); } CommandLineArguments commandLineArguments = this._commandLineArgumentsFactory.CreateCommandLineArguments(list, executedProject.Directory, false, RuntimeEnvironment.GetRuntimeDirectory()); MetadataFileReferenceResolver pathResolver = new MetadataFileReferenceResolver(commandLineArguments.ReferencePaths, commandLineArguments.BaseDirectory); metadataReferences = commandLineArguments.ResolveMetadataReferences(new AssemblyReferenceResolver(pathResolver, this._metadataService.GetProvider())); IAnalyzerAssemblyLoader loader = this._analyzerService.GetLoader(); foreach (var path in commandLineArguments.AnalyzerReferences.Select((r) => r.FilePath)) { loader.AddDependencyLocation(path); } analyzerReferences = commandLineArguments.ResolveAnalyzerReferences(loader); }
internal void ResolveAnalyzersFromArguments( string language, List <DiagnosticInfo> diagnostics, CommonMessageProvider messageProvider, IAnalyzerAssemblyLoader analyzerLoader, bool skipAnalyzers, out ImmutableArray <DiagnosticAnalyzer> analyzers, out ImmutableArray <ISourceGenerator> generators) { var analyzerBuilder = ImmutableArray.CreateBuilder <DiagnosticAnalyzer>(); var generatorBuilder = ImmutableArray.CreateBuilder <ISourceGenerator>(); EventHandler <AnalyzerLoadFailureEventArgs> errorHandler = (o, e) => { var analyzerReference = o as AnalyzerFileReference; RoslynDebug.Assert(analyzerReference is object); DiagnosticInfo?diagnostic; switch (e.ErrorCode) { case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToLoadAnalyzer: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_UnableToLoadAnalyzer, analyzerReference.FullPath, e.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.UnableToCreateAnalyzer: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_AnalyzerCannotBeCreated, e.TypeName ?? "", analyzerReference.FullPath, e.Message); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.NoAnalyzers: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_NoAnalyzerInAssembly, analyzerReference.FullPath); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.ReferencesFramework: diagnostic = new DiagnosticInfo(messageProvider, messageProvider.WRN_AnalyzerReferencesFramework, analyzerReference.FullPath, e.TypeName !); break; case AnalyzerLoadFailureEventArgs.FailureErrorCode.None: default: return; } // Filter this diagnostic based on the compilation options so that /nowarn and /warnaserror etc. take effect. diagnostic = messageProvider.FilterDiagnosticInfo(diagnostic, this.CompilationOptions); if (diagnostic != null) { diagnostics.Add(diagnostic); } }; var resolvedReferences = ArrayBuilder <AnalyzerFileReference> .GetInstance(); foreach (var reference in AnalyzerReferences) { var resolvedReference = ResolveAnalyzerReference(reference, analyzerLoader); if (resolvedReference != null) { resolvedReferences.Add(resolvedReference); // register the reference to the analyzer loader: analyzerLoader.AddDependencyLocation(resolvedReference.FullPath); } else { diagnostics.Add(new DiagnosticInfo(messageProvider, messageProvider.ERR_MetadataFileNotFound, reference.FilePath)); } } // All analyzer references are registered now, we can start loading them. foreach (var resolvedReference in resolvedReferences) { resolvedReference.AnalyzerLoadFailed += errorHandler; resolvedReference.AddAnalyzers(analyzerBuilder, language, shouldIncludeAnalyzer); resolvedReference.AddGenerators(generatorBuilder, language); resolvedReference.AnalyzerLoadFailed -= errorHandler; } resolvedReferences.Free(); generators = generatorBuilder.ToImmutable(); analyzers = analyzerBuilder.ToImmutable(); // If we are skipping analyzers, ensure that we only add suppressors. bool shouldIncludeAnalyzer(DiagnosticAnalyzer analyzer) => !skipAnalyzers || analyzer is DiagnosticSuppressor; }
public void AddDependencyLocation(string fullPath) { _impl.AddDependencyLocation(fullPath); }