No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AssemblyNameProvider.cs 7.0KB

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