public static IEnumerable <CompilerInvocation> GetInvocations(Options options = null, IEnumerable <string> logFiles = null) { var analyzer = new LogAnalyzer(); var invocationBuckets = new Dictionary <string, IEnumerable <CompilerInvocation> >(StringComparer.OrdinalIgnoreCase); using (Disposable.Timing("Analyzing log files")) { #if true Parallel.ForEach(logFiles, logFile => { var set = analyzer.AnalyzeLogFile(logFile); lock (invocationBuckets) { invocationBuckets.Add(Path.GetFileNameWithoutExtension(logFile), set); } }); #else foreach (var logFile in logFiles) { var set = analyzer.AnalyzeLogFile(logFile); lock (invocationBuckets) { invocationBuckets.Add(Path.GetFileNameWithoutExtension(logFile), set); } } #endif } var buckets = invocationBuckets.OrderBy(kvp => kvp.Key).ToArray(); foreach (var bucket in buckets) { foreach (var invocation in bucket.Value) { analyzer.SelectFinalInvocation(invocation); } } FixOutputPaths(analyzer); if (options != null && options.SanityCheck) { using (Disposable.Timing("Sanity check")) { SanityCheck(analyzer, options); } } return(analyzer.Invocations); }
private static void FixOutputPaths(LogAnalyzer analyzer) { foreach (var invocation in analyzer.Invocations) { // TypeScript if (invocation.OutputAssemblyPath == null) { continue; } if (invocation.OutputAssemblyPath.StartsWith(".") || invocation.OutputAssemblyPath.StartsWith("\\")) { invocation.OutputAssemblyPath = Path.GetFullPath( Path.Combine( Path.GetDirectoryName(invocation.ProjectFilePath), invocation.OutputAssemblyPath)); } invocation.OutputAssemblyPath = Path.GetFullPath(invocation.OutputAssemblyPath); invocation.ProjectFilePath = Path.GetFullPath(invocation.ProjectFilePath); } }
private static void SanityCheck(LogAnalyzer analyzer, Options options = null) { var dupes = analyzer.Invocations .Where(i => i.AssemblyName != null) .GroupBy(i => i.AssemblyName, StringComparer.OrdinalIgnoreCase) .Where(g => g.Count() > 1).ToArray(); if (dupes.Any()) { foreach (var dupe in dupes) { Log.Exception("=== Dupes: " + dupe.Key); foreach (var value in dupe) { Log.Exception(value.ToString()); } } } var ambiguousProjects = analyzer.assemblyNameToProjectFilePathsMap.Where(kvp => kvp.Value.Count > 1).ToArray(); if (ambiguousProjects.Any()) { foreach (var ambiguousProject in ambiguousProjects) { Log.Exception("Multiple projects for the same assembly name: " + ambiguousProject.Key); foreach (var value in ambiguousProject.Value) { Log.Exception(value); } } } var ambiguousIntermediatePaths = analyzer.intermediateAssemblyPathToOutputAssemblyPathMap .GroupBy(kvp => Path.GetFileNameWithoutExtension(kvp.Key), StringComparer.OrdinalIgnoreCase) .Where(g => g.Count() > 1) .OrderByDescending(g => g.Count()); if (ambiguousIntermediatePaths.Any()) { } if (analyzer.ambiguousFinalDestinations.Any()) { } foreach (var assemblyName in ambiguousInvocations.Keys.ToArray()) { var values = ambiguousInvocations[assemblyName].ToArray(); bool shouldRemove = true; for (int i = 1; i < values.Length; i++) { if (!values[i].OutputAssemblyPath.Equals(values[0].OutputAssemblyPath)) { // if entries in a bucket are different, we keep the bucket to report it at the end shouldRemove = false; break; } } // remove buckets where all entries are exactly the same if (shouldRemove) { ambiguousInvocations.Remove(assemblyName); } } if (ambiguousInvocations.Any()) { foreach (var ambiguousInvocation in ambiguousInvocations) { Log.Exception("Ambiguous invocations for the same assembly name: " + ambiguousInvocation.Key); foreach (var value in ambiguousInvocation.Value) { Log.Exception(value.ToString()); } } } if (options.CheckForNonExistingReferences) { DumpNonExistingReferences(); } }
private static void SanityCheck(LogAnalyzer analyzer, Options options = null) { var dupes = analyzer.Invocations .Where(i => i.AssemblyName != null) .GroupBy(i => i.AssemblyName, StringComparer.OrdinalIgnoreCase) .Where(g => g.Count() > 1).ToArray(); if (dupes.Any()) { foreach (var dupe in dupes) { Log.Exception("=== Dupes: " + dupe.Key); foreach (var value in dupe) { Log.Exception(value.ToString()); } } } var ambiguousProjects = analyzer.assemblyNameToProjectFilePathsMap.Where(kvp => kvp.Value.Count > 1).ToArray(); if (ambiguousProjects.Any()) { foreach (var ambiguousProject in ambiguousProjects) { Log.Exception("Multiple projects for the same assembly name: " + ambiguousProject.Key); foreach (var value in ambiguousProject.Value) { Log.Exception(value); } } } var ambiguousIntermediatePaths = analyzer.intermediateAssemblyPathToOutputAssemblyPathMap .GroupBy(kvp => Path.GetFileNameWithoutExtension(kvp.Key), StringComparer.OrdinalIgnoreCase) .Where(g => g.Count() > 1) .OrderByDescending(g => g.Count()); if (ambiguousIntermediatePaths.Any()) { } if (analyzer.ambiguousFinalDestinations.Any()) { } foreach (var assemblyName in ambiguousInvocations.Keys.ToArray()) { var values = ambiguousInvocations[assemblyName].ToArray(); bool shouldRemove = true; for (int i = 1; i < values.Length; i++) { if (!values[i].OutputAssemblyPath.Equals(values[0].OutputAssemblyPath)) { // if entries in a bucket are different, we keep the bucket to report it at the end shouldRemove = false; break; } } // remove buckets where all entries are exactly the same if (shouldRemove) { ambiguousInvocations.Remove(assemblyName); } } if (ambiguousInvocations.Any()) { foreach (var ambiguousInvocation in ambiguousInvocations) { Log.Exception("Ambiguous invocations for the same assembly name: " + ambiguousInvocation.Key); foreach (var value in ambiguousInvocation.Value) { Log.Exception(value.ToString()); } } } if (options.CheckForNonExistingReferences) { DumpNonExistingReferences(); } }
private static void FixOutputPaths(LogAnalyzer analyzer) { foreach (var invocation in analyzer.Invocations) { // TypeScript if (invocation.OutputAssemblyPath == null) { continue; } if (invocation.OutputAssemblyPath.StartsWith(".") || invocation.OutputAssemblyPath.StartsWith("\\")) { invocation.OutputAssemblyPath = Path.GetFullPath( Path.Combine( Path.GetDirectoryName(invocation.ProjectFilePath), invocation.OutputAssemblyPath)); } invocation.OutputAssemblyPath = Path.GetFullPath(invocation.OutputAssemblyPath); invocation.ProjectFilePath = Path.GetFullPath(invocation.ProjectFilePath); } }
public static IEnumerable<CompilerInvocation> GetInvocations(Options options = null, IEnumerable<string> logFiles = null) { var analyzer = new LogAnalyzer(); var invocationBuckets = new Dictionary<string, IEnumerable<CompilerInvocation>>(StringComparer.OrdinalIgnoreCase); using (Disposable.Timing("Analyzing log files")) { #if true Parallel.ForEach(logFiles, logFile => { var set = analyzer.AnalyzeLogFile(logFile); lock (invocationBuckets) { invocationBuckets.Add(Path.GetFileNameWithoutExtension(logFile), set); } }); #else foreach (var logFile in logFiles) { var set = analyzer.AnalyzeLogFile(logFile); lock (invocationBuckets) { invocationBuckets.Add(Path.GetFileNameWithoutExtension(logFile), set); } } #endif } var buckets = invocationBuckets.OrderBy(kvp => kvp.Key).ToArray(); foreach (var bucket in buckets) { foreach (var invocation in bucket.Value) { analyzer.SelectFinalInvocation(invocation); } } FixOutputPaths(analyzer); if (options != null && options.SanityCheck) { using (Disposable.Timing("Sanity check")) { SanityCheck(analyzer, options); } } return analyzer.Invocations; }