예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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();
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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;
        }