PageRenderTime 39ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/DotNetProjectConfiguration.cs

http://github.com/mono/monodevelop
C# | 304 lines | 223 code | 42 blank | 39 comment | 42 complexity | 5b0a57c8478a9b0d67ecf85cc988618e MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0, CC-BY-SA-3.0, MIT, LGPL-2.1, Apache-2.0, BSD-3-Clause
  1. //
  2. // DotNetProjectConfiguration.cs
  3. //
  4. // Author:
  5. // Lluis Sanchez Gual
  6. //
  7. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Linq;
  30. using MonoDevelop.Core;
  31. using MonoDevelop.Core.Assemblies;
  32. using MonoDevelop.Core.StringParsing;
  33. using System.Collections.Generic;
  34. namespace MonoDevelop.Projects
  35. {
  36. public enum CompileTarget {
  37. Exe,
  38. Library,
  39. WinExe,
  40. Module
  41. };
  42. public class DotNetProjectConfiguration: ProjectConfiguration
  43. {
  44. string assembly;
  45. string sourcePath;
  46. DotNetCompilerParameters compilationParameters;
  47. public bool? AppendTargetFrameworkToOutputPath { get; set; }
  48. public string TargetFrameworkShortName { get; internal set; } = string.Empty;
  49. public DotNetProjectConfiguration (string id): base (id)
  50. {
  51. }
  52. internal protected override void Read (IPropertySet pset)
  53. {
  54. base.Read (pset);
  55. //we are assuming that if AppendTargetFrameworkToOutputPath has a value is .NET Core / .NET Standard proj.
  56. AppendTargetFrameworkToOutputPath = pset.GetValue<bool?> ("AppendTargetFrameworkToOutputPath", defaultValue: null);
  57. TargetFrameworkShortName = pset.GetValue ("TargetFramework");
  58. assembly = pset.GetValue ("AssemblyName");
  59. SignAssembly = pset.GetValue<bool> ("SignAssembly");
  60. DelaySign = pset.GetValue<bool> ("DelaySign");
  61. PublicSign = pset.GetValue<bool> (nameof(PublicSign));
  62. AssemblyKeyFile = pset.GetPathValue ("AssemblyOriginatorKeyFile", FilePath.Empty);
  63. if (string.IsNullOrEmpty (AssemblyKeyFile))
  64. AssemblyKeyFile = pset.GetPathValue ("AssemblyKeyFile", FilePath.Empty);
  65. if (compilationParameters != null)
  66. compilationParameters.Read (pset);
  67. }
  68. internal protected override void Write (IPropertySet pset)
  69. {
  70. base.Write (pset);
  71. pset.SetValue ("AssemblyName", assembly, mergeToMainGroup: true);
  72. pset.SetValue ("SignAssembly", SignAssembly, defaultValue:false, mergeToMainGroup: true);
  73. pset.SetValue ("DelaySign", DelaySign, defaultValue:false, mergeToMainGroup:true);
  74. pset.SetValue (nameof(PublicSign), PublicSign, defaultValue: false, mergeToMainGroup: true);
  75. pset.SetValue ("AssemblyOriginatorKeyFile", AssemblyKeyFile, defaultValue:FilePath.Empty, mergeToMainGroup:true);
  76. if (compilationParameters != null)
  77. compilationParameters.Write (pset);
  78. if (AppendTargetFrameworkToOutputPath ?? true) {
  79. pset.RemoveProperty (nameof (AppendTargetFrameworkToOutputPath));
  80. } else {
  81. pset.SetValue (nameof (AppendTargetFrameworkToOutputPath), false);
  82. }
  83. }
  84. public bool SignAssembly { get; set; } = false;
  85. public bool DelaySign { get; set; } = false;
  86. public bool PublicSign { get; set; }
  87. internal string OldAssemblyKeyFile {
  88. set { AssemblyKeyFile = value; }
  89. }
  90. public FilePath AssemblyKeyFile { get; set; } = FilePath.Empty;
  91. public virtual string OutputAssembly {
  92. get { return assembly; }
  93. set { assembly = value; }
  94. }
  95. public virtual CompileTarget CompileTarget {
  96. get {
  97. if (ParentItem is DotNetProject prj)
  98. return prj.CompileTarget;
  99. return CompileTarget.Library;
  100. }
  101. }
  102. public override SolutionItemConfiguration FindBestMatch (SolutionItemConfigurationCollection configurations)
  103. {
  104. // Get all configurations with the same value for the 'DEBUG' symbol
  105. var isDebug = compilationParameters.GetDefineSymbols ().Contains ("DEBUG");
  106. var matches = configurations.OfType<DotNetProjectConfiguration> ().Where (c =>
  107. c.CompilationParameters.GetDefineSymbols ().Contains ("DEBUG") == isDebug
  108. ).ToArray ();
  109. // If the base method can't find a direct match then try to match based on finding a configuration
  110. // with a matching value for the 'DEBUG' symbol and some other heuristics
  111. return base.FindBestMatch (configurations)
  112. ?? matches.FirstOrDefault (c => Platform == c.Platform)
  113. ?? matches.FirstOrDefault (c => c.Platform == "");
  114. }
  115. TargetFramework targetFramework;
  116. public TargetFramework TargetFramework {
  117. get {
  118. if (targetFramework != null)
  119. return targetFramework;
  120. if (ParentItem is DotNetProject prj)
  121. return prj.TargetFramework;
  122. return Services.ProjectService.DefaultTargetFramework;
  123. }
  124. internal set {
  125. targetFramework = value;
  126. }
  127. }
  128. public TargetRuntime TargetRuntime {
  129. get {
  130. if (ParentItem is DotNetProject prj)
  131. return prj.TargetRuntime;
  132. return Runtime.SystemAssemblyService.DefaultRuntime;
  133. }
  134. }
  135. public MonoDevelop.Core.ClrVersion ClrVersion {
  136. get {
  137. #pragma warning disable CS0618 // Type or member is obsolete
  138. return TargetFramework.ClrVersion;
  139. #pragma warning restore CS0618 // Type or member is obsolete
  140. }
  141. }
  142. public DotNetCompilerParameters CompilationParameters {
  143. get { return compilationParameters; }
  144. set {
  145. compilationParameters = value;
  146. if (compilationParameters != null)
  147. compilationParameters.ParentConfiguration = this;
  148. }
  149. }
  150. public FilePath CompiledOutputName {
  151. get {
  152. if (OutputAssembly == null)
  153. return FilePath.Empty;
  154. FilePath fullPath = OutputDirectory.Combine (OutputAssembly);
  155. if (OutputAssembly.EndsWith (".dll") || OutputAssembly.EndsWith (".exe"))
  156. return fullPath;
  157. else
  158. return fullPath + (CompileTarget == CompileTarget.Library ? ".dll" : ".exe");
  159. }
  160. }
  161. protected override void OnCopyFrom (ItemConfiguration configuration, bool isRename)
  162. {
  163. base.OnCopyFrom (configuration, isRename);
  164. var conf = (DotNetProjectConfiguration) configuration;
  165. AppendTargetFrameworkToOutputPath = conf.AppendTargetFrameworkToOutputPath;
  166. TargetFrameworkShortName = conf.TargetFrameworkShortName ?? "unknown";
  167. assembly = conf.assembly;
  168. sourcePath = conf.sourcePath;
  169. bool notifyParentItem = ParentItem != null;
  170. if (ParentItem == null)
  171. SetParentItem (conf.ParentItem);
  172. CompilationParameters = conf.compilationParameters != null ? conf.compilationParameters.Clone () : null;
  173. if (notifyParentItem)
  174. ParentItem?.NotifyModified ("CompilerParameters");
  175. SignAssembly = conf.SignAssembly;
  176. DelaySign = conf.DelaySign;
  177. AssemblyKeyFile = conf.AssemblyKeyFile;
  178. }
  179. public new DotNetProject ParentItem => (DotNetProject)base.ParentItem;
  180. public virtual IEnumerable<string> GetDefineSymbols ()
  181. {
  182. if (CompilationParameters != null)
  183. return CompilationParameters.GetDefineSymbols ();
  184. return new string[0];
  185. }
  186. public override ConfigurationSelector Selector {
  187. get {
  188. string framework = GetMultiTargetFrameworkShortName ();
  189. if (string.IsNullOrEmpty (framework))
  190. return base.Selector;
  191. string id = Name;
  192. if (!string.IsNullOrEmpty (Platform))
  193. id += "|" + Platform;
  194. var selector = new ItemConfigurationSelector (id);
  195. return new DotNetProjectFrameworkConfigurationSelector (selector, framework);
  196. }
  197. }
  198. internal DotNetProjectConfiguration GetConfiguration (string framework)
  199. {
  200. if (ParentItem == null)
  201. return null;
  202. return ParentItem.GetConfiguration (Name, Platform, framework) as DotNetProjectConfiguration;
  203. }
  204. /// <summary>
  205. /// Returns short name for TargetFramework only if the project is a multi-target framework project.
  206. /// </summary>
  207. internal string GetMultiTargetFrameworkShortName ()
  208. {
  209. if (IsMultiTarget)
  210. return TargetFrameworkShortName;
  211. return null;
  212. }
  213. /// <summary>
  214. /// Do not want to change the Id for single framework since this is displayed in the UI. Only when getting
  215. /// project information such as References for a specific framework do we want to change the Id since it is
  216. /// used for caching.
  217. /// </summary>
  218. internal bool IsMultiTarget { get; set; }
  219. internal protected override string GetId ()
  220. {
  221. bool hasPlatform = !string.IsNullOrEmpty (Platform);
  222. bool hasFramework = IsMultiTarget && !string.IsNullOrEmpty (TargetFrameworkShortName);
  223. if (hasPlatform && hasFramework)
  224. return Name + "|" + Platform + "|" + TargetFrameworkShortName;
  225. else if (hasPlatform)
  226. return Name + "|" + Platform;
  227. else if (hasFramework)
  228. return Name + "||" + TargetFrameworkShortName;
  229. else
  230. return Name;
  231. }
  232. }
  233. [Mono.Addins.Extension]
  234. class ProjectTagProvider: StringTagProvider<DotNetProjectConfiguration>, IStringTagProvider
  235. {
  236. public override IEnumerable<StringTagDescription> GetTags ()
  237. {
  238. yield return new StringTagDescription ("ProjectConfig", GettextCatalog.GetString ("Project Configuration"));
  239. yield return new StringTagDescription ("ProjectConfigName", GettextCatalog.GetString ("Project Configuration Name"));
  240. yield return new StringTagDescription ("ProjectConfigPlat", GettextCatalog.GetString ("Project Configuration Platform"));
  241. yield return new StringTagDescription ("TargetFile", GettextCatalog.GetString ("Target File"));
  242. yield return new StringTagDescription ("TargetPath", GettextCatalog.GetString ("Target Path"));
  243. yield return new StringTagDescription ("TargetName", GettextCatalog.GetString ("Target Name"));
  244. yield return new StringTagDescription ("TargetDir", GettextCatalog.GetString ("Target Directory"));
  245. yield return new StringTagDescription ("TargetExt", GettextCatalog.GetString ("Target Extension"));
  246. }
  247. public override object GetTagValue (DotNetProjectConfiguration conf, string tag)
  248. {
  249. switch (tag) {
  250. case "TARGETPATH":
  251. case "TARGETFILE": return conf.CompiledOutputName;
  252. case "TARGETNAME": return conf.CompiledOutputName.FileName;
  253. case "TARGETDIR": return conf.CompiledOutputName.ParentDirectory;
  254. case "TARGETEXT": return conf.CompiledOutputName.Extension;
  255. case "PROJECTCONFIG": return string.IsNullOrEmpty (conf.Platform) ? conf.Name : conf.Name + "." + conf.Platform;
  256. case "PROJECTCONFIGNAME": return conf.Name;
  257. case "PROJECTCONFIGPLAT": return conf.Platform;
  258. }
  259. throw new NotSupportedException ();
  260. }
  261. }
  262. }