public void CompilerMessageIsReported()
        {
            LogAssert.ignoreFailingMessages = true;

            CompilerMessage[] defaultAssemblyCompilerMessages = null;
            using (var compilationHelper = new AssemblyCompilationPipeline
            {
                AssemblyCompilationFinished = (assemblyName, messages) =>
                {
                    if (assemblyName.Equals(AssemblyInfo.DefaultAssemblyName))
                    {
                        defaultAssemblyCompilerMessages = messages;
                    }
                }
            })
            {
                compilationHelper.Compile();
            }

#if UNITY_EDITOR_WIN
            const string expectedMessage = "Assets\\ProjectAuditor-Temp\\MyClass.cs(6,1): error CS1519: Invalid token '}' in class, struct, or interface member declaration";
#else
            const string expectedMessage = "Assets/ProjectAuditor-Temp/MyClass.cs(6,1): error CS1519: Invalid token '}' in class, struct, or interface member declaration";
#endif
            LogAssert.Expect(LogType.Error, expectedMessage);
            LogAssert.Expect(LogType.Error, "Failed to compile player scripts");
            LogAssert.ignoreFailingMessages = false;

            Assert.NotNull(defaultAssemblyCompilerMessages);
            Assert.AreEqual(1, defaultAssemblyCompilerMessages.Length);
            Assert.True(defaultAssemblyCompilerMessages[0].message.Equals(expectedMessage));
        }
        public void CompilerMessageIsReported()
        {
            LogAssert.ignoreFailingMessages = true;

            CompilerMessage[] defaultAssemblyCompilerMessages = null;
            using (var compilationPipeline = new AssemblyCompilationPipeline
            {
                AssemblyCompilationFinished = (assemblyName, messages) =>
                {
                    if (assemblyName.Equals(AssemblyInfo.DefaultAssemblyName))
                    {
                        defaultAssemblyCompilerMessages = messages;
                    }
                }
            })
            {
                compilationPipeline.Compile();
            }

            LogAssert.Expect(LogType.Error, k_ExpectedMessage);
            LogAssert.Expect(LogType.Error, "Failed to compile player scripts");
            LogAssert.ignoreFailingMessages = false;

            Assert.NotNull(defaultAssemblyCompilerMessages);
            Assert.AreEqual(1, defaultAssemblyCompilerMessages.Length);
            Assert.True(defaultAssemblyCompilerMessages[0].code.Equals(k_ExpectedCode));
            Assert.True(defaultAssemblyCompilerMessages[0].message.Equals(k_ExpectedDescription));
            Assert.AreEqual(CompilerMessageType.Error, defaultAssemblyCompilerMessages[0].type);
        }
        public void DefaultAssemblyIsCompiled()
        {
            using (var compilationHelper = new AssemblyCompilationPipeline())
            {
                var assemblyInfos = compilationHelper.Compile();

                Assert.Positive(assemblyInfos.Count());
                Assert.NotNull(assemblyInfos.FirstOrDefault(info => info.name.Equals(AssemblyInfo.DefaultAssemblyName)));
            }
        }
예제 #4
0
        public void Audit(Action <ProjectIssue> onIssueFound, Action onComplete, IProgressBar progressBar = null)
        {
            if (m_ProblemDescriptors == null)
            {
                throw new Exception("Issue Database not initialized.");
            }

            if (m_Config.AnalyzeInBackground && m_AssemblyAnalysisThread != null)
            {
                m_AssemblyAnalysisThread.Join();
            }

            var compilationPipeline = new AssemblyCompilationPipeline
            {
                AssemblyCompilationFinished = (assemblyName, compilerMessages) => ProcessCompilerMessages(assemblyName, compilerMessages, onIssueFound)
            };

            Profiler.BeginSample("ScriptAuditor.Audit.Compilation");
            var assemblyInfos = compilationPipeline.Compile(m_Config.AnalyzeEditorCode, progressBar);

            Profiler.EndSample();

            var callCrawler           = new CallCrawler();
            var issues                = new List <ProjectIssue>();
            var localAssemblyInfos    = assemblyInfos.Where(info => !info.readOnly).ToArray();
            var readOnlyAssemblyInfos = assemblyInfos.Where(info => info.readOnly).ToArray();

            var assemblyDirectories = new List <string>();

            assemblyDirectories.AddRange(AssemblyInfoProvider.GetPrecompiledAssemblyDirectories(PrecompiledAssemblyTypes.UserAssembly | PrecompiledAssemblyTypes.UnityEngine));
            if (m_Config.AnalyzeEditorCode)
            {
                assemblyDirectories.AddRange(AssemblyInfoProvider.GetPrecompiledAssemblyDirectories(PrecompiledAssemblyTypes.UnityEditor));
            }

            var onCallFound = new Action <CallInfo>(pair =>
            {
                callCrawler.Add(pair);
            });

            var onCompleteInternal = new Action <IProgressBar>(bar =>
            {
                compilationPipeline.Dispose();
                callCrawler.BuildCallHierarchies(issues, bar);
                onComplete();
            });

            var onIssueFoundInternal = new Action <ProjectIssue>(issue =>
            {
                if (issue.category == IssueCategory.Code)
                {
                    issues.Add(issue);
                }
                onIssueFound(issue);
            });

            Profiler.BeginSample("ScriptAuditor.Audit.Analysis");

            // first phase: analyze assemblies generated from editable scripts
            AnalyzeAssemblies(localAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, null, progressBar);

            var enableBackgroundAnalysis = m_Config.AnalyzeInBackground;

#if !UNITY_2019_3_OR_NEWER
            enableBackgroundAnalysis = false;
#endif
            // second phase: analyze all remaining assemblies, in a separate thread if enableBackgroundAnalysis is enabled
            if (enableBackgroundAnalysis)
            {
                m_AssemblyAnalysisThread = new Thread(() =>
                                                      AnalyzeAssemblies(readOnlyAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, onCompleteInternal));
                m_AssemblyAnalysisThread.Name     = "Assembly Analysis";
                m_AssemblyAnalysisThread.Priority = ThreadPriority.BelowNormal;
                m_AssemblyAnalysisThread.Start();
            }
            else
            {
                Profiler.BeginSample("ScriptAuditor.Audit.AnalysisReadOnly");
                AnalyzeAssemblies(readOnlyAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, onCompleteInternal, progressBar);
                Profiler.EndSample();
            }
            Profiler.EndSample();
        }