A game about forced loneliness, made by TACStudios
at master 220 lines 7.2 kB view raw
1/*--------------------------------------------------------------------------------------------- 2 * Copyright (c) Unity Technologies. 3 * Copyright (c) Microsoft Corporation. All rights reserved. 4 * Licensed under the MIT License. See License.txt in the project root for license information. 5 *--------------------------------------------------------------------------------------------*/ 6using System; 7using System.Collections.Generic; 8using System.Linq; 9using UnityEditor; 10using UnityEditor.Compilation; 11using UnityEditor.PackageManager; 12 13namespace Microsoft.Unity.VisualStudio.Editor 14{ 15 public interface IAssemblyNameProvider 16 { 17 string[] ProjectSupportedExtensions { get; } 18 string ProjectGenerationRootNamespace { get; } 19 ProjectGenerationFlag ProjectGenerationFlag { get; } 20 21 string GetAssemblyNameFromScriptPath(string path); 22 string GetAssemblyName(string assemblyOutputPath, string assemblyName); 23 bool IsInternalizedPackagePath(string path); 24 IEnumerable<Assembly> GetAssemblies(Func<string, bool> shouldFileBePartOfSolution); 25 IEnumerable<string> GetAllAssetPaths(); 26 UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath); 27 ResponseFileData ParseResponseFile(string responseFilePath, string projectDirectory, string[] systemReferenceDirectories); 28 void ToggleProjectGeneration(ProjectGenerationFlag preference); 29 } 30 31 public class AssemblyNameProvider : IAssemblyNameProvider 32 { 33 private readonly Dictionary<string, UnityEditor.PackageManager.PackageInfo> m_PackageInfoCache = new Dictionary<string, UnityEditor.PackageManager.PackageInfo>(); 34 35 ProjectGenerationFlag m_ProjectGenerationFlag = (ProjectGenerationFlag)EditorPrefs.GetInt( 36 "unity_project_generation_flag", 37 (int)(ProjectGenerationFlag.Local | ProjectGenerationFlag.Embedded)); 38 39 public string[] ProjectSupportedExtensions => EditorSettings.projectGenerationUserExtensions; 40 41 public string ProjectGenerationRootNamespace => EditorSettings.projectGenerationRootNamespace; 42 43 public ProjectGenerationFlag ProjectGenerationFlag 44 { 45 get { return ProjectGenerationFlagImpl; } 46 private set { ProjectGenerationFlagImpl = value;} 47 } 48 49 internal virtual ProjectGenerationFlag ProjectGenerationFlagImpl 50 { 51 get => m_ProjectGenerationFlag; 52 private set 53 { 54 EditorPrefs.SetInt("unity_project_generation_flag", (int)value); 55 m_ProjectGenerationFlag = value; 56 } 57 } 58 59 public string GetAssemblyNameFromScriptPath(string path) 60 { 61 return CompilationPipeline.GetAssemblyNameFromScriptPath(path); 62 } 63 64 internal static readonly string AssemblyOutput = @"Temp\bin\Debug\".NormalizePathSeparators(); 65 internal static readonly string PlayerAssemblyOutput = @"Temp\bin\Debug\Player\".NormalizePathSeparators(); 66 67 public IEnumerable<Assembly> GetAssemblies(Func<string, bool> shouldFileBePartOfSolution) 68 { 69 IEnumerable<Assembly> assemblies = GetAssembliesByType(AssembliesType.Editor, shouldFileBePartOfSolution, AssemblyOutput); 70 71 if (!ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.PlayerAssemblies)) 72 { 73 return assemblies; 74 } 75 var playerAssemblies = GetAssembliesByType(AssembliesType.Player, shouldFileBePartOfSolution, PlayerAssemblyOutput); 76 return assemblies.Concat(playerAssemblies); 77 } 78 79 private static IEnumerable<Assembly> GetAssembliesByType(AssembliesType type, Func<string, bool> shouldFileBePartOfSolution, string outputPath) 80 { 81 foreach (var assembly in CompilationPipeline.GetAssemblies(type)) 82 { 83 if (assembly.sourceFiles.Any(shouldFileBePartOfSolution)) 84 { 85 yield return new Assembly( 86 assembly.name, 87 outputPath, 88 assembly.sourceFiles, 89 assembly.defines, 90 assembly.assemblyReferences, 91 assembly.compiledAssemblyReferences, 92 assembly.flags, 93 assembly.compilerOptions 94#if UNITY_2020_2_OR_NEWER 95 , assembly.rootNamespace 96#endif 97 ); 98 } 99 } 100 } 101 102 public string GetCompileOutputPath(string assemblyName) 103 { 104 // We need to keep this one for API surface check (AssemblyNameProvider is public), but not used anymore 105 throw new NotImplementedException(); 106 } 107 108 public IEnumerable<string> GetAllAssetPaths() 109 { 110 return AssetDatabase.GetAllAssetPaths(); 111 } 112 113 private static string ResolvePotentialParentPackageAssetPath(string assetPath) 114 { 115 const string packagesPrefix = "packages/"; 116 if (!assetPath.StartsWith(packagesPrefix, StringComparison.OrdinalIgnoreCase)) 117 { 118 return null; 119 } 120 121 var followupSeparator = assetPath.IndexOf('/', packagesPrefix.Length); 122 if (followupSeparator == -1) 123 { 124 return assetPath.ToLowerInvariant(); 125 } 126 127 return assetPath.Substring(0, followupSeparator).ToLowerInvariant(); 128 } 129 130 public UnityEditor.PackageManager.PackageInfo FindForAssetPath(string assetPath) 131 { 132 var parentPackageAssetPath = ResolvePotentialParentPackageAssetPath(assetPath); 133 if (parentPackageAssetPath == null) 134 { 135 return null; 136 } 137 138 if (m_PackageInfoCache.TryGetValue(parentPackageAssetPath, out var cachedPackageInfo)) 139 { 140 return cachedPackageInfo; 141 } 142 143 var result = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(parentPackageAssetPath); 144 m_PackageInfoCache[parentPackageAssetPath] = result; 145 return result; 146 } 147 148 public bool IsInternalizedPackagePath(string path) 149 { 150 if (string.IsNullOrEmpty(path.Trim())) 151 { 152 return false; 153 } 154 var packageInfo = FindForAssetPath(path); 155 if (packageInfo == null) 156 { 157 return false; 158 } 159 var packageSource = packageInfo.source; 160 switch (packageSource) 161 { 162 case PackageSource.Embedded: 163 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.Embedded); 164 case PackageSource.Registry: 165 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.Registry); 166 case PackageSource.BuiltIn: 167 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.BuiltIn); 168 case PackageSource.Unknown: 169 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.Unknown); 170 case PackageSource.Local: 171 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.Local); 172 case PackageSource.Git: 173 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.Git); 174 case PackageSource.LocalTarball: 175 return !ProjectGenerationFlag.HasFlag(ProjectGenerationFlag.LocalTarBall); 176 } 177 178 return false; 179 } 180 181 public ResponseFileData ParseResponseFile(string responseFilePath, string projectDirectory, string[] systemReferenceDirectories) 182 { 183 return CompilationPipeline.ParseResponseFile( 184 responseFilePath, 185 projectDirectory, 186 systemReferenceDirectories 187 ); 188 } 189 190 public void ToggleProjectGeneration(ProjectGenerationFlag preference) 191 { 192 if (ProjectGenerationFlag.HasFlag(preference)) 193 { 194 ProjectGenerationFlag ^= preference; 195 } 196 else 197 { 198 ProjectGenerationFlag |= preference; 199 } 200 } 201 202 internal void ResetPackageInfoCache() 203 { 204 m_PackageInfoCache.Clear(); 205 } 206 207 public void ResetProjectGenerationFlag() 208 { 209 ProjectGenerationFlag = ProjectGenerationFlag.None; 210 } 211 212 public string GetAssemblyName(string assemblyOutputPath, string assemblyName) 213 { 214 if (assemblyOutputPath == PlayerAssemblyOutput) 215 return assemblyName + ".Player"; 216 217 return assemblyName; 218 } 219 } 220}