/src/AddIns/Misc/PackageManagement/Project/Src/EnvDTE/Project.cs

https://github.com/ajadex/SharpDevelop · C# · 356 lines · 282 code · 57 blank · 17 comment · 10 complexity · 96d18b864c38ee0c0dc819a1e8fdbe15 MD5 · raw file

  1. // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Collections.Generic;
  20. using System.IO;
  21. using System.Linq;
  22. using ICSharpCode.Core;
  23. using ICSharpCode.NRefactory.TypeSystem;
  24. using ICSharpCode.SharpDevelop;
  25. using ICSharpCode.SharpDevelop.Dom;
  26. using ICSharpCode.SharpDevelop.Gui;
  27. using ICSharpCode.SharpDevelop.Project;
  28. using ICSharpCode.SharpDevelop.Workbench;
  29. using Microsoft.Build.Construction;
  30. using SD = ICSharpCode.SharpDevelop.Project;
  31. namespace ICSharpCode.PackageManagement.EnvDTE
  32. {
  33. public class Project : MarshalByRefObject, global::EnvDTE.Project
  34. {
  35. IPackageManagementProjectService projectService;
  36. IPackageManagementFileService fileService;
  37. DTE dte;
  38. CodeModelContext context;
  39. public Project(MSBuildBasedProject project)
  40. : this(
  41. project,
  42. new PackageManagementProjectService(),
  43. new PackageManagementFileService())
  44. {
  45. }
  46. public Project(
  47. MSBuildBasedProject project,
  48. IPackageManagementProjectService projectService,
  49. IPackageManagementFileService fileService)
  50. {
  51. this.MSBuildProject = project;
  52. this.projectService = projectService;
  53. this.fileService = fileService;
  54. context = new CodeModelContext {
  55. CurrentProject = project,
  56. DteProject = this
  57. };
  58. CreateProperties();
  59. Object = new ProjectObject(this);
  60. ProjectItems = new ProjectItems(this, this);
  61. }
  62. public Project()
  63. {
  64. }
  65. internal IPackageManagementFileService FileService {
  66. get { return fileService; }
  67. }
  68. void CreateProperties()
  69. {
  70. var propertyFactory = new ProjectPropertyFactory(this);
  71. Properties = new Properties(propertyFactory);
  72. }
  73. public virtual string Name {
  74. get { return MSBuildProject.Name; }
  75. }
  76. public virtual string UniqueName {
  77. get { return GetUniqueName(); }
  78. }
  79. string GetUniqueName()
  80. {
  81. return FileUtility.GetRelativePath(MSBuildProject.ParentSolution.Directory, FileName);
  82. }
  83. public virtual string FileName {
  84. get { return MSBuildProject.FileName; }
  85. }
  86. public virtual string FullName {
  87. get { return FileName; }
  88. }
  89. public virtual object Object { get; private set; }
  90. public virtual global::EnvDTE.Properties Properties { get; private set; }
  91. public virtual global::EnvDTE.ProjectItems ProjectItems { get; private set; }
  92. public virtual global::EnvDTE.DTE DTE {
  93. get {
  94. if (dte == null) {
  95. dte = new DTE(projectService, fileService);
  96. }
  97. return dte;
  98. }
  99. }
  100. public virtual string Type {
  101. get { return GetProjectType(); }
  102. }
  103. string GetProjectType()
  104. {
  105. return ProjectType.GetProjectType(MSBuildProject);
  106. }
  107. public virtual string Kind {
  108. get { return GetProjectKind(); }
  109. }
  110. string GetProjectKind()
  111. {
  112. return new ProjectKind(this).Kind;
  113. }
  114. internal MSBuildBasedProject MSBuildProject { get; private set; }
  115. public virtual void Save()
  116. {
  117. projectService.Save(MSBuildProject);
  118. }
  119. internal virtual void AddReference(string path)
  120. {
  121. if (!HasReference(path)) {
  122. var referenceItem = new ReferenceProjectItem(MSBuildProject, path);
  123. AddProjectItemToMSBuildProject(referenceItem);
  124. }
  125. }
  126. bool HasReference(string include)
  127. {
  128. foreach (ReferenceProjectItem reference in GetReferences()) {
  129. if (IsReferenceMatch(reference, include)) {
  130. return true;
  131. }
  132. }
  133. return false;
  134. }
  135. void AddProjectItemToMSBuildProject(SD.ProjectItem projectItem)
  136. {
  137. projectService.AddProjectItem(MSBuildProject, projectItem);
  138. }
  139. internal IEnumerable<SD.ProjectItem> GetReferences()
  140. {
  141. return MSBuildProject.GetItemsOfType(ItemType.Reference);
  142. }
  143. bool IsReferenceMatch(ReferenceProjectItem reference, string include)
  144. {
  145. return String.Equals(reference.Include, include, StringComparison.InvariantCultureIgnoreCase);
  146. }
  147. internal void RemoveReference(ReferenceProjectItem referenceItem)
  148. {
  149. projectService.RemoveProjectItem(MSBuildProject, referenceItem);
  150. }
  151. internal ProjectItem AddFileProjectItemUsingFullPath(string path)
  152. {
  153. string dependentUpon = GetDependentUpon(path);
  154. return AddFileProjectItemWithDependentUsingFullPath(path, dependentUpon);
  155. }
  156. string GetDependentUpon(string path)
  157. {
  158. var dependentFile = new DependentFile(MSBuildProject);
  159. FileProjectItem projectItem = dependentFile.GetParentFileProjectItem(path);
  160. if (projectItem != null) {
  161. return Path.GetFileName(projectItem.Include);
  162. }
  163. return null;
  164. }
  165. internal ProjectItem AddFileProjectItemWithDependentUsingFullPath(string path, string dependentUpon)
  166. {
  167. FileProjectItem fileProjectItem = CreateFileProjectItemUsingFullPath(path);
  168. fileProjectItem.FileName = ICSharpCode.Core.FileName.Create(path);
  169. fileProjectItem.DependentUpon = dependentUpon;
  170. AddProjectItemToMSBuildProject(fileProjectItem);
  171. return new ProjectItem(this, fileProjectItem);
  172. }
  173. FileProjectItem CreateFileProjectItemUsingPathRelativeToProject(string include)
  174. {
  175. ItemType itemType = GetDefaultItemType(include);
  176. return CreateFileProjectItemUsingPathRelativeToProject(itemType, include);
  177. }
  178. ItemType GetDefaultItemType(string include)
  179. {
  180. return MSBuildProject.GetDefaultItemType(Path.GetFileName(include));
  181. }
  182. FileProjectItem CreateFileProjectItemUsingPathRelativeToProject(ItemType itemType, string include)
  183. {
  184. var fileItem = new FileProjectItem(MSBuildProject, itemType) {
  185. Include = include
  186. };
  187. if (IsLink(include)) {
  188. fileItem.SetEvaluatedMetadata("Link", Path.GetFileName(include));
  189. }
  190. return fileItem;
  191. }
  192. bool IsLink(string include)
  193. {
  194. return include.StartsWith("..");
  195. }
  196. FileProjectItem CreateFileProjectItemUsingFullPath(string path)
  197. {
  198. string relativePath = GetRelativePath(path);
  199. return CreateFileProjectItemUsingPathRelativeToProject(relativePath);
  200. }
  201. internal IList<string> GetAllPropertyNames()
  202. {
  203. var names = new List<string>();
  204. lock (MSBuildProject.SyncRoot) {
  205. foreach (ProjectPropertyElement propertyElement in MSBuildProject.MSBuildProjectFile.Properties) {
  206. names.Add(propertyElement.Name);
  207. }
  208. names.Add("OutputFileName");
  209. names.Add("LocalPath");
  210. }
  211. return names;
  212. }
  213. public virtual global::EnvDTE.CodeModel CodeModel {
  214. get { return new CodeModel(context, this); }
  215. }
  216. public virtual global::EnvDTE.ConfigurationManager ConfigurationManager {
  217. get { return new ConfigurationManager(this); }
  218. }
  219. internal virtual string GetLowercaseFileExtension()
  220. {
  221. return Path.GetExtension(FileName).ToLowerInvariant();
  222. }
  223. internal virtual void DeleteFile(string fileName)
  224. {
  225. fileService.RemoveFile(fileName);
  226. }
  227. internal ProjectItem AddDirectoryProjectItemUsingFullPath(string directory)
  228. {
  229. AddDirectoryProjectItemsRecursively(directory);
  230. return DirectoryProjectItem.CreateDirectoryProjectItemFromFullPath(this, directory);
  231. }
  232. void AddDirectoryProjectItemsRecursively(string directory)
  233. {
  234. string[] files = fileService.GetFiles(directory);
  235. string[] childDirectories = fileService.GetDirectories(directory);
  236. if (files.Any()) {
  237. foreach (string file in files) {
  238. AddFileProjectItemUsingFullPath(file);
  239. }
  240. } else if (!childDirectories.Any()) {
  241. AddDirectoryProjectItemToMSBuildProject(directory);
  242. }
  243. foreach (string childDirectory in childDirectories) {
  244. AddDirectoryProjectItemsRecursively(childDirectory);
  245. }
  246. }
  247. void AddDirectoryProjectItemToMSBuildProject(string directory)
  248. {
  249. FileProjectItem projectItem = CreateMSBuildProjectItemForDirectory(directory);
  250. AddProjectItemToMSBuildProject(projectItem);
  251. }
  252. FileProjectItem CreateMSBuildProjectItemForDirectory(string directory)
  253. {
  254. return new FileProjectItem(MSBuildProject, ItemType.Folder) {
  255. FileName = ICSharpCode.Core.FileName.Create(directory)
  256. };
  257. }
  258. internal string GetRelativePath(string path)
  259. {
  260. return FileUtility.GetRelativePath(MSBuildProject.Directory, path);
  261. }
  262. internal IProjectBrowserUpdater CreateProjectBrowserUpdater()
  263. {
  264. return projectService.CreateProjectBrowserUpdater();
  265. }
  266. internal ICompilation GetCompilationUnit(string fileName)
  267. {
  268. return fileService.GetCompilationUnit(fileName);
  269. }
  270. internal ICompilation GetCompilationUnit()
  271. {
  272. return fileService.GetCompilationUnit(MSBuildProject);
  273. }
  274. internal void RemoveProjectItem(ProjectItem projectItem)
  275. {
  276. projectService.RemoveProjectItem(MSBuildProject, projectItem.MSBuildProjectItem);
  277. }
  278. internal ProjectItem FindProjectItem(string fileName)
  279. {
  280. return ProjectItem.FindByFileName(MSBuildProject, fileName);
  281. }
  282. internal IViewContent GetOpenFile(string fileName)
  283. {
  284. return fileService.GetOpenFile(fileName);
  285. }
  286. internal void OpenFile(string fileName)
  287. {
  288. fileService.OpenFile(fileName);
  289. }
  290. internal bool IsFileFileInsideProjectFolder(string filePath)
  291. {
  292. return FileUtility.IsBaseDirectory(MSBuildProject.Directory, filePath);
  293. }
  294. internal void SaveFile(IViewContent view)
  295. {
  296. fileService.SaveFile(view);
  297. }
  298. }
  299. }