Exemplo n.º 1
0
 private static ScriptAssembly[] CodeGenAssemblies(ScriptAssembly[] assemblies) =>
 assemblies
 .Where(assembly => UnityCodeGenHelpers.IsCodeGen(FileUtil.GetPathWithoutExtension(assembly.Filename)))
 .SelectMany(assembly => assembly.AllRecursiveScripAssemblyReferencesIncludingSelf())
 .Distinct()
 .OrderBy(a => a.Filename)
 .ToArray();
Exemplo n.º 2
0
        public static bool ShouldAddTestRunnerReferences(TargetAssembly targetAssembly)
        {
            if (UnityCodeGenHelpers.IsCodeGen(targetAssembly.Filename))
            {
                return(false);
            }

            bool referencesTestRunnerAssembly = false;

            foreach (var reference in targetAssembly.References)
            {
                referencesTestRunnerAssembly =
                    reference.Filename.Equals(k_EditorTestRunnerAssemblyName, StringComparison.Ordinal) ||
                    reference.Filename.Equals(k_EngineTestRunnerAssemblyName, StringComparison.Ordinal);

                if (referencesTestRunnerAssembly)
                {
                    break;
                }
            }

            return(!referencesTestRunnerAssembly &&
                   !targetAssembly.Filename.Equals(k_EditorTestRunnerAssemblyName, StringComparison.Ordinal) &&
                   !targetAssembly.Filename.Equals(k_EngineTestRunnerAssemblyName, StringComparison.Ordinal) &&
                   (PlayerSettings.playModeTestRunnerEnabled || (targetAssembly.Flags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly));
        }
Exemplo n.º 3
0
        public static bool ShouldAddTestRunnerReferences(EditorBuildRules.TargetAssembly targetAssembly)
        {
            if (UnityCodeGenHelpers.IsCodeGen(targetAssembly.Filename))
            {
                return(false);
            }

            return(!targetAssembly.References.Any(x => x.Filename.Contains(k_EngineTestRunnerAssemblyName) || x.Filename.Contains(k_EditorTestRunnerAssemblyName)) &&
                   !targetAssembly.Filename.Contains(k_EngineTestRunnerAssemblyName) &&
                   !targetAssembly.Filename.Contains(k_EditorTestRunnerAssemblyName) &&
                   (PlayerSettings.playModeTestRunnerEnabled || (targetAssembly.Flags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly));
        }
Exemplo n.º 4
0
        public List <CompilerMessage> PostProcess(ScriptAssembly assembly, List <CompilerMessage> messages, string outputTempPath)
        {
            var hasCompileError = messages.Any(m => m.type == CompilerMessageType.Error);

            if (hasCompileError)
            {
                return(messages);
            }

            if (UnityCodeGenHelpers.IsCodeGen(assembly.Filename))
            {
                return(messages);
            }

            if (!HasPostProcessors)
            {
                return(messages);
            }

            try
            {
                List <DiagnosticMessage> diagnostics = RunILPostProcessors(assembly, outputTempPath);
                foreach (var message in diagnostics)
                {
                    if (message.DiagnosticType == DiagnosticType.Error)
                    {
                        hasCompileError = true;
                    }
                    messages.Add(new CompilerMessage
                    {
                        assemblyName = message.File,
                        column       = message.Column,
                        line         = message.Line,
                        message      = message.MessageData,
                        type         = message.DiagnosticType == DiagnosticType.Error ? CompilerMessageType.Error : CompilerMessageType.Warning,
                    });
                }
            }
            catch (Exception exception)
            {
                messages.Add(new CompilerMessage
                {
                    assemblyName = assembly.Filename,
                    message      = $"Something went wrong while Post Processing the assembly ({assembly.Filename}) : {Environment.NewLine} {exception.Message} {Environment.NewLine}{exception.StackTrace}",
                    type         = CompilerMessageType.Error,
                });
            }

            return(messages);
        }
        public void ValidateFields()
        {
            if (string.IsNullOrEmpty(name))
                throw new System.Exception("Required property 'name' not set");

            if ((excludePlatforms != null && excludePlatforms.Length > 0) &&
                (includePlatforms != null && includePlatforms.Length > 0))
                throw new System.Exception("Both 'excludePlatforms' and 'includePlatforms' are set.");

            if (autoReferenced && UnityCodeGenHelpers.IsCodeGen(name, includesExtension: false))
            {
                throw new Exception($"Assembly '{name}' is a CodeGen assembly and cannot be Auto Referenced");
            }
        }
Exemplo n.º 6
0
        internal static ScriptAssembly[] ToScriptAssemblies(
            IDictionary <TargetAssembly, DirtyTargetAssembly> targetAssemblies,
            ScriptAssemblySettings settings,
            CompilationAssemblies assemblies, ICompilationSetupWarningTracker warningSink, ISafeModeInfo safeModeInfo)
        {
            var scriptAssemblies = new ScriptAssembly[targetAssemblies.Count];

            var targetToScriptAssembly = new Dictionary <TargetAssembly, ScriptAssembly>();
            int index = 0;

            bool buildingForEditor = settings.BuildingForEditor;
            var  safeModeWhiteList = new HashSet <string>(safeModeInfo.GetWhiteListAssemblyNames());

            foreach (var entry in targetAssemblies)
            {
                var targetAssembly      = entry.Key;
                var dirtyTargetAssembly = entry.Value;
                var scriptAssembly      = new ScriptAssembly();

                // Setup TargetAssembly -> ScriptAssembly mapping for converting references
                scriptAssemblies[index] = scriptAssembly;
                targetToScriptAssembly[targetAssembly] = scriptAssemblies[index++];

                // Setup ScriptAssembly
                scriptAssembly.Flags         = targetAssembly.Flags;
                scriptAssembly.BuildTarget   = settings.BuildTarget;
                scriptAssembly.OriginPath    = targetAssembly.PathPrefix;
                scriptAssembly.Filename      = targetAssembly.Filename;
                scriptAssembly.SkipCodeGen   = safeModeWhiteList.Contains(targetAssembly.Filename);
                scriptAssembly.RootNamespace = targetAssembly.Type == TargetAssemblyType.Predefined ? settings.ProjectRootNamespace : targetAssembly.RootNamespace;

                scriptAssembly.OutputDirectory    = settings.OutputDirectory;
                scriptAssembly.Defines            = targetAssembly.Defines == null ? s_CSharpVersionDefines : targetAssembly.Defines.Concat(s_CSharpVersionDefines).ToArray();
                scriptAssembly.Files              = dirtyTargetAssembly.SourceFiles.ToArray();
                scriptAssembly.TargetAssemblyType = targetAssembly.Type;
                scriptAssembly.AsmDefPath         = targetAssembly.AsmDefPath;

                if (scriptAssembly.TargetAssemblyType == TargetAssemblyType.Predefined)
                {
                    scriptAssembly.CompilerOptions = new ScriptCompilerOptions(settings.PredefinedAssembliesCompilerOptions);
                }
                else
                {
                    scriptAssembly.CompilerOptions = targetAssembly.CompilerOptions;
                }

                scriptAssembly.CompilerOptions.RoslynAnalyzerDllPaths      = new string[0];
                scriptAssembly.CompilerOptions.RoslynAnalyzerRulesetPath   = string.Empty;
                scriptAssembly.CompilerOptions.AdditionalCompilerArguments = settings.AdditionalCompilerArguments;

                var editorOnlyTargetAssembly = (targetAssembly.Flags & AssemblyFlags.EditorOnly) == AssemblyFlags.EditorOnly;

                if (editorOnlyTargetAssembly)
                {
                    scriptAssembly.CompilerOptions.ApiCompatibilityLevel = ApiCompatibilityLevel.NET_Unity_4_8;
                }
                else
                {
                    scriptAssembly.CompilerOptions.ApiCompatibilityLevel = settings.PredefinedAssembliesCompilerOptions.ApiCompatibilityLevel;
                }

                if ((settings.CompilationOptions & EditorScriptCompilationOptions.BuildingUseDeterministicCompilation) == EditorScriptCompilationOptions.BuildingUseDeterministicCompilation)
                {
                    scriptAssembly.CompilerOptions.UseDeterministicCompilation = true;
                }
                else
                {
                    scriptAssembly.CompilerOptions.UseDeterministicCompilation = false;
                }

                scriptAssembly.CompilerOptions.CodeOptimization = settings.CodeOptimization;
            }

            // Don't add the auto-referenced engine assemblies if the assembly either has the flag set, or
            // is a codegen assembly
            AutoReferencedPackageAssemblies.AddReferences(assemblies.CustomTargetAssemblies, settings.CompilationOptions,
                                                          t =>
            {
                var hasNoEngineReferencesFlag = (t.Flags & AssemblyFlags.NoEngineReferences) == AssemblyFlags.NoEngineReferences;
                if (hasNoEngineReferencesFlag)
                {
                    return(false);
                }

                return(!UnityCodeGenHelpers.IsCodeGen(t.Filename));
            });

            // Setup ScriptAssembly references
            index = 0;
            foreach (var entry in targetAssemblies)
            {
                var scriptAssembly = scriptAssemblies[index++];
                AddScriptAssemblyReferences(ref scriptAssembly, entry.Key, settings, assemblies, targetToScriptAssembly, warningSink);

                if (UnityCodeGenHelpers.IsCodeGen(entry.Key.Filename) ||
                    UnityCodeGenHelpers.IsCodeGenTest(entry.Key.Filename) ||
                    CompilationPipelineCommonHelper.ShouldAdd(entry.Key.Filename))
                {
                    CompilationPipelineCommonHelper.UpdateScriptAssemblyReference(ref scriptAssembly);
                }

                if (!buildingForEditor)
                {
                    PlatformSupportModuleHelpers.AddAdditionalPlatformSupportData(settings.CompilationExtension, ref scriptAssembly);
                }
            }

            if ((settings.CompilationOptions & EditorScriptCompilationOptions.BuildingWithRoslynAnalysis) != 0)
            {
                var analyzers = assemblies.RoslynAnalyzerDllPaths;
                foreach (var a in analyzers)
                {
                    var targetAssemblyOwningAnalyzer = assemblies.CustomTargetAssemblies.Values
                                                       .OrderBy(c => c.PathFilter(a)).LastOrDefault();

                    if (targetAssemblyOwningAnalyzer?.PathFilter(a) <= 0)
                    {
                        targetAssemblyOwningAnalyzer = null;
                    }

                    foreach (var scriptAssembly in scriptAssemblies)
                    {
                        if (ShouldUseAnalyzerForScriptAssembly(scriptAssembly, targetAssemblyOwningAnalyzer))
                        {
                            scriptAssembly.CompilerOptions.RoslynAnalyzerDllPaths    = scriptAssembly.CompilerOptions.RoslynAnalyzerDllPaths.Concat(new[] { a }).ToArray();
                            scriptAssembly.CompilerOptions.RoslynAnalyzerRulesetPath =
                                scriptAssembly.TargetAssemblyType == TargetAssemblyType.Predefined
                                ? RuleSetFileCache.GetRuleSetFilePathInRootFolder(Path.ChangeExtension(scriptAssembly.Filename, null))
                                : RuleSetFileCache.GetPathForAssembly(scriptAssembly.OriginPath);
                        }
                    }
                }
            }

            return(scriptAssemblies);
        }
Exemplo n.º 7
0
        // Returns true when compilation is finished due to one of these reasons
        // * Was stopped (CompilationTask.Stopped will be true)
        // * Compilation had errors (CompilationTask.CompileErrors will be true)
        // * Compilation succesfully completed without errors.
        public bool Poll()
        {
            HandleOnCompilationTaskStarted();

            if (Stopped)
            {
                HandleOnCompilationTaskFinished();
                return(true);
            }

            Dictionary <ScriptAssembly, ScriptCompilerBase> finishedCompilerTasks = null;

            // Check if any compiler processes are finished.
            foreach (var task in compilerTasks)
            {
                var compiler = task.Value;

                // Did compiler task finish?
                if (compiler.Poll())
                {
                    if (finishedCompilerTasks == null)
                    {
                        finishedCompilerTasks = new Dictionary <ScriptAssembly, ScriptCompilerBase>();
                    }

                    var assembly = task.Key;
                    finishedCompilerTasks.Add(assembly, compiler);
                }
            }

            // Save compiler messages from finished compiler processes and check for compile errors.
            if (finishedCompilerTasks != null)
            {
                foreach (var task in finishedCompilerTasks)
                {
                    var assembly = task.Key;
                    var compiler = task.Value;

                    var messages     = compiler.GetCompilerMessages();
                    var messagesList = messages.ToList();

                    compiledAssemblies.Add(assembly, messagesList.ToArray());

                    bool havePostProcessors = ilPostProcessing != null && ilPostProcessing.HasPostProcessors;
                    bool isCodeGenAssembly  = codeGenAssemblies.Contains(assembly);
                    bool hasCompileErrors   = messagesList.Any(m => m.type == CompilerMessageType.Error);

                    if (isCodeGenAssembly)
                    {
                        if (hasCompileErrors)
                        {
                            notCompiledCodeGenAssemblies.Add(assembly);
                        }
                        else
                        {
                            compiledCodeGenAssemblies.Add(assembly);
                        }
                    }

                    if (havePostProcessors &&
                        notCompiledCodeGenAssemblies.Count == 0 &&
                        !hasCompileErrors &&
                        !isCodeGenAssembly)
                    {
                        var assemblySourcePath = AssetPath.Combine(buildOutputDirectory, assembly.Filename);
                        var pdbSourcePath      = AssetPath.Combine(buildOutputDirectory, assembly.PdbFilename);

                        try
                        {
                            if (assemblySourcePath != assembly.FullPath)
                            {
                                File.Copy(assemblySourcePath, assembly.FullPath, true);
                            }

                            if (pdbSourcePath != assembly.PdbFullPath)
                            {
                                File.Copy(pdbSourcePath, assembly.PdbFullPath, true);
                            }

                            var postProcessorTask = new PostProcessorTask(assembly, messagesList, buildOutputDirectory, ilPostProcessing);
                            pendingPostProcessorTasks.Add(postProcessorTask);
                        }
                        catch (IOException e)
                        {
                            UnityEngine.Debug.LogError($"Fail to copy {assemblySourcePath} or {pdbSourcePath} to {AssetPath.GetDirectoryName(assembly.FullPath)} before post processing the assembly. Skipping post processing.\n{e}");
                            // OnCompilationFinished callbacks might add more compiler messages
                            OnCompilationFinished?.Invoke(assembly, messagesList);
                            processedAssemblies.Add(assembly, messagesList.ToArray());
                        }
                    }
                    else
                    {
                        // OnCompilationFinished callbacks might add more compiler messages
                        OnCompilationFinished?.Invoke(assembly, messagesList);
                        processedAssemblies.Add(assembly, messagesList.ToArray());
                    }

                    if (!CompileErrors)
                    {
                        CompileErrors = messagesList.Any(m => m.type == CompilerMessageType.Error);
                    }

                    // If a codgen / IL Post processor has compile errors, clear
                    // pending assemblies waiting for compilation and assemblies
                    // waiting to get post processed.
                    if (isCodeGenAssembly && hasCompileErrors)
                    {
                        pendingPostProcessorTasks.Clear();
                        pendingAssemblies.Clear();
                    }

                    compilerTasks.Remove(assembly);
                    compiler.Dispose();
                }
            }


            if (ilPostProcessing != null && ilPostProcessing.HasPostProcessors)
            {
                PollPostProcessors();
            }

            // If StopOnFirstError is set, do not queue assemblies for compilation in case of compile errors.
            bool stopOnFirstError = (compilationTaskOptions & CompilationTaskOptions.StopOnFirstError) == CompilationTaskOptions.StopOnFirstError;

            if (stopOnFirstError && CompileErrors)
            {
                foreach (var pendingAssembly in pendingAssemblies)
                {
                    if (UnityCodeGenHelpers.IsCodeGen(pendingAssembly.Filename))
                    {
                        notCompiledCodeGenAssemblies.Add(pendingAssembly);
                    }
                }

                pendingAssemblies.Clear();

                if (FinishedCompilation)
                {
                    HandleOnCompilationTaskFinished();
                }

                return(FinishedCompilation);
            }

            // Queue pending assemblies for compilation if we have no running compilers or if compilers have finished.
            if (compilerTasks.Count == 0 || (finishedCompilerTasks != null && finishedCompilerTasks.Count > 0))
            {
                QueuePendingAssemblies();
            }

            if (FinishedCompilation)
            {
                HandleOnCompilationTaskFinished();
            }

            return(FinishedCompilation);
        }