Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/monodevelop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikayla Hutchinson <m.j.hutchinson@gmail.com>2018-04-24 01:49:51 +0300
committerGitHub <noreply@github.com>2018-04-24 01:49:51 +0300
commite665ba6c0d378907891338d12411ac235c75bf25 (patch)
tree6a4ae1f19635e2ef2f91853235184dd4d3e42cbe
parent6aba0c4e88d85d30613cd606200873f255981f22 (diff)
parent1ee3fbeaa449b83e9a0007668de423bec7537cab (diff)
Merge pull request #4648 from mono/assemblyservice-caching
Improve SystemAssemblyService initialization time
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/FrameworkInfo.cs152
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MonoFrameworkBackend.cs66
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MsNetFrameworkBackend.cs27
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SupportedFramework.cs132
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs175
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkBackend.cs56
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs127
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj1
-rw-r--r--main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/PortableRuntimeSelectorDialog.cs8
9 files changed, 410 insertions, 334 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/FrameworkInfo.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/FrameworkInfo.cs
new file mode 100644
index 0000000000..6bdbc01b5d
--- /dev/null
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/FrameworkInfo.cs
@@ -0,0 +1,152 @@
+//
+// Copyright (c) 2008 Novell, Inc (http://www.novell.com)
+// Copyright (c) Microsoft Corp.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml;
+using System.Reflection;
+using System.Text;
+
+namespace MonoDevelop.Core.Assemblies
+{
+ class FrameworkInfo
+ {
+ public TargetFrameworkMoniker Id { get; set; }
+ public string Name { get; set; }
+ public string IncludeFramework { get; set; }
+ public string TargetFrameworkDirectory { get; set; }
+ public List<AssemblyInfo> Assemblies { get; set; }
+ public List<SupportedFramework> SupportedFrameworks { get; set; }
+
+ public static FrameworkInfo Load (TargetFrameworkMoniker moniker, FilePath frameworkListFile)
+ {
+ var info = new FrameworkInfo { Id = moniker };
+
+ //for non-cached files, this file is in the RedistList subdir of the assembly dir
+ info.TargetFrameworkDirectory = frameworkListFile.ParentDirectory.ParentDirectory;
+
+ using (var reader = XmlReader.Create (frameworkListFile)) {
+ if (!reader.ReadToDescendant ("FileList"))
+ throw new Exception ("Missing FileList element");
+
+ if (reader.MoveToAttribute ("Name") && reader.ReadAttributeValue ())
+ info.Name = reader.ReadContentAsString ();
+
+ if (reader.MoveToAttribute ("IncludeFramework") && reader.ReadAttributeValue ()) {
+ string include = reader.ReadContentAsString ();
+ if (!string.IsNullOrEmpty (include))
+ info.IncludeFramework = include;
+ }
+
+ //this is a Mono-specific extension
+ if (reader.MoveToAttribute ("TargetFrameworkDirectory") && reader.ReadAttributeValue ()) {
+ string targetDir = reader.ReadContentAsString ();
+ if (!string.IsNullOrEmpty (targetDir)) {
+ targetDir = targetDir.Replace ('\\', Path.DirectorySeparatorChar);
+ info.TargetFrameworkDirectory = frameworkListFile.ParentDirectory.Combine (targetDir).FullPath;
+ }
+ }
+
+ info.Assemblies = new List<AssemblyInfo> ();
+ info.SupportedFrameworks = new List<SupportedFramework> ();
+
+ while (reader.Read ()) {
+ if (reader.IsStartElement ()) {
+ switch (reader.LocalName) {
+ case "File":
+ info.Assemblies.Add (ReadFileElement (reader));
+ break;
+ case "SupportedFramework":
+ info.SupportedFrameworks.Add (SupportedFramework.LoadFromAttributes (reader));
+ break;
+ }
+ }
+ }
+ }
+ return info;
+ }
+
+ static AssemblyInfo ReadFileElement (XmlReader reader)
+ {
+ var ainfo = new AssemblyInfo ();
+ if (reader.MoveToAttribute ("AssemblyName") && reader.ReadAttributeValue ())
+ ainfo.Name = reader.ReadContentAsString ();
+ if (string.IsNullOrEmpty (ainfo.Name))
+ throw new Exception ("Missing AssemblyName attribute");
+ if (reader.MoveToAttribute ("Version") && reader.ReadAttributeValue ())
+ ainfo.Version = reader.ReadContentAsString ();
+ if (reader.MoveToAttribute ("PublicKeyToken") && reader.ReadAttributeValue ())
+ ainfo.PublicKeyToken = reader.ReadContentAsString ();
+ if (reader.MoveToAttribute ("Culture") && reader.ReadAttributeValue ())
+ ainfo.Culture = reader.ReadContentAsString ();
+ if (reader.MoveToAttribute ("ProcessorArchitecture") && reader.ReadAttributeValue ())
+ ainfo.ProcessorArchitecture = (ProcessorArchitecture)
+ Enum.Parse (typeof (ProcessorArchitecture), reader.ReadContentAsString (), true);
+ if (reader.MoveToAttribute ("InGac") && reader.ReadAttributeValue ())
+ ainfo.InGac = reader.ReadContentAsBoolean ();
+ return ainfo;
+ }
+
+ public void Save (string path)
+ {
+ using (var writer = XmlWriter.Create (path, new XmlWriterSettings { Encoding = Encoding.UTF8 })) {
+ writer.WriteStartDocument ();
+ writer.WriteStartElement ("FileList");
+ WriteNonEmptyAttribute ("Name", Name);
+ WriteNonEmptyAttribute ("IncludeFramework", IncludeFramework);
+ WriteNonEmptyAttribute ("TargetFrameworkDirectory", TargetFrameworkDirectory);
+ if (Assemblies.Count > 0) {
+ foreach (var asm in Assemblies) {
+ writer.WriteStartElement ("File");
+ writer.WriteAttributeString ("AssemblyName", asm.Name);
+ WriteNonEmptyAttribute ("Version", asm.Version);
+ WriteNonEmptyAttribute ("PublicKeyToken", asm.PublicKeyToken);
+ WriteNonEmptyAttribute ("Culture", asm.Culture);
+ if (asm.ProcessorArchitecture != ProcessorArchitecture.None) {
+ writer.WriteAttributeString ("ProcessorArchitecture", asm.ProcessorArchitecture.ToString ());
+ }
+ if (asm.InGac) {
+ writer.WriteAttributeString ("InGac", "true");
+ }
+ writer.WriteEndElement ();
+ }
+ }
+ if (SupportedFrameworks.Count > 0) {
+ foreach (var sf in SupportedFrameworks) {
+ sf.SaveAsElement (writer);
+ }
+ }
+ writer.WriteEndDocument ();
+
+ void WriteNonEmptyAttribute (string name, string val)
+ {
+ if (!string.IsNullOrEmpty (val)) {
+ writer.WriteAttributeString (name, val);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MonoFrameworkBackend.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MonoFrameworkBackend.cs
index 13a67e6608..924cfc39f2 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MonoFrameworkBackend.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MonoFrameworkBackend.cs
@@ -32,18 +32,11 @@ namespace MonoDevelop.Core.Assemblies
{
public class MonoFrameworkBackend: TargetFrameworkBackend<MonoTargetRuntime>
{
- string ref_assemblies_folder;
-
- string GetReferenceAssembliesFolder ()
+ protected override string OnGetReferenceAssembliesFolder ()
{
- if (ref_assemblies_folder != null)
- return ref_assemblies_folder;
- var fxDir = framework.Id.GetAssemblyDirectoryName ();
- foreach (var rootDir in ((MonoTargetRuntime)runtime).GetReferenceFrameworkDirectories ()) {
- var dir = rootDir.Combine (fxDir);
+ FilePath dir = base.OnGetReferenceAssembliesFolder ();
+ if (dir != null) {
var frameworkList = dir.Combine ("RedistList", "FrameworkList.xml");
- if (!File.Exists (frameworkList))
- continue;
//check for the Mono-specific TargetFrameworkDirectory extension
using (var reader = System.Xml.XmlReader.Create (frameworkList)) {
if (reader.ReadToDescendant ("FileList") && reader.MoveToAttribute ("TargetFrameworkDirectory") && reader.ReadAttributeValue ()) {
@@ -54,62 +47,11 @@ namespace MonoDevelop.Core.Assemblies
}
}
}
- ref_assemblies_folder = dir;
return dir;
}
return null;
}
-
- public override IEnumerable<string> GetFrameworkFolders ()
- {
- var dir = GetReferenceAssembliesFolder ();
- if (dir != null)
- yield return dir;
-
- if (framework.Id.Identifier != TargetFrameworkMoniker.ID_NET_FRAMEWORK)
- yield break;
-
- string subdir;
- switch (framework.Id.Version) {
- case "1.1":
- subdir = "1.0"; break;
- case "3.0":
- // WCF is installed in the 2.0 directory. Others (olive) in 3.0.
- yield return Path.Combine (targetRuntime.MonoDirectory, "2.0");
- yield return Path.Combine (targetRuntime.MonoDirectory, "3.0");
- yield break;
- case "3.5":
- yield return Path.Combine (targetRuntime.MonoDirectory, "3.5");
- subdir = "2.0"; break;
- default:
- subdir = framework.Id.Version; break;
- }
- yield return Path.Combine (targetRuntime.MonoDirectory, subdir);
- }
-
- public override bool IsInstalled {
- get {
- if (framework.Id.Identifier == TargetFrameworkMoniker.ID_NET_FRAMEWORK &&
- framework.Id.Version == "3.0")
- {
- // This is a special case. The WCF assemblies are installed in the 2.0 directory.
- // There are other 3.0 assemblies which belong to the olive package (WCF doesn't)
- // and which are installed in the 3.0 directory. We consider 3.0 to be installed
- // if any of those assemblies are installed.
- if (base.IsInstalled)
- return true;
- string dir = Path.Combine (targetRuntime.MonoDirectory, "2.0");
- if (Directory.Exists (dir)) {
- string firstAsm = Path.Combine (dir, "System.ServiceModel.dll");
- return File.Exists (firstAsm);
- }
- return false;
- }
- return base.IsInstalled;
- }
- }
-
-
+
string GetOldMcsName (TargetFrameworkMoniker fx)
{
//old compilers for specific frameworks
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MsNetFrameworkBackend.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MsNetFrameworkBackend.cs
index c92ddaf68b..75344ca43f 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MsNetFrameworkBackend.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/MsNetFrameworkBackend.cs
@@ -25,39 +25,12 @@
// THE SOFTWARE.
using System;
-using Microsoft.Win32;
-using System.IO;
using System.Collections.Generic;
namespace MonoDevelop.Core.Assemblies
{
public class MsNetFrameworkBackend: TargetFrameworkBackend<MsNetTargetRuntime>
{
- string ref_assemblies_folder;
-
- string GetReferenceAssembliesFolder ()
- {
- if (ref_assemblies_folder != null)
- return ref_assemblies_folder;
-
- var fxDir = framework.Id.GetAssemblyDirectoryName ();
- foreach (var rootDir in runtime.GetReferenceFrameworkDirectories ()) {
- var dir = rootDir.Combine (fxDir);
- var frameworkList = dir.Combine ("RedistList", "FrameworkList.xml");
- if (File.Exists (frameworkList))
- return ref_assemblies_folder = dir;
- }
- return null;
- }
-
- public override IEnumerable<string> GetFrameworkFolders ()
- {
- var dir = GetReferenceAssembliesFolder ();
- if (dir != null) {
- yield return dir;
- }
- }
-
public override Dictionary<string, string> GetToolsEnvironmentVariables ()
{
var vars = new Dictionary<string, string> ();
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SupportedFramework.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SupportedFramework.cs
index 28c1c14924..c6f22ef554 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SupportedFramework.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SupportedFramework.cs
@@ -24,7 +24,6 @@
// THE SOFTWARE.
using System;
-using System.IO;
using System.Xml;
using System.Collections.Generic;
@@ -33,9 +32,18 @@ namespace MonoDevelop.Core.Assemblies
public class SupportedFramework
{
public static readonly Version NoMaximumVersion = new Version (int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue);
- public static readonly Version NoMinumumVersion = new Version (0, 0, 0, 0);
+ public static readonly Version NoMinimumVersion = new Version (0, 0, 0, 0);
+ [Obsolete("This was misspelled, use NoMinimumVersion")]
+ public static readonly Version NoMinumumVersion = NoMinimumVersion;
+
+ [Obsolete("Use the overload without a TargetFramework parameter")]
public SupportedFramework (TargetFramework target, string identifier, string display, string profile, Version minVersion, string minDisplayVersion)
+ : this (identifier, display, profile, minVersion, minDisplayVersion)
+ {
+ }
+
+ public SupportedFramework (string identifier, string display, string profile, Version minVersion, string minDisplayVersion)
{
MinimumVersionDisplayName = minDisplayVersion;
MinimumVersion = minVersion;
@@ -43,20 +51,16 @@ namespace MonoDevelop.Core.Assemblies
DisplayName = display;
Identifier = identifier;
Profile = profile;
-
- TargetFramework = target;
}
- internal SupportedFramework (TargetFramework target)
+ internal SupportedFramework ()
{
MinimumVersionDisplayName = string.Empty;
- MinimumVersion = NoMinumumVersion;
+ MinimumVersion = NoMinimumVersion;
MaximumVersion = NoMaximumVersion;
DisplayName = string.Empty;
Identifier = string.Empty;
Profile = string.Empty;
-
- TargetFramework = target;
}
public string DisplayName {
@@ -90,10 +94,10 @@ namespace MonoDevelop.Core.Assemblies
public string MonoSpecificVersionDisplayName {
get; internal set;
}
-
- public TargetFramework TargetFramework {
- get; private set;
- }
+
+ //this referred to the "parent" rather than framework decsribed by this instance
+ [Obsolete ("This property was misleading and is no longer supported")]
+ public TargetFramework TargetFramework => TargetFramework.Default;
static Version ParseVersion (string version, Version wildcard)
{
@@ -103,55 +107,85 @@ namespace MonoDevelop.Core.Assemblies
return Version.Parse (version);
}
- internal static SupportedFramework Load (TargetFramework target, FilePath path)
+ internal static SupportedFramework Load (FilePath path)
{
- SupportedFramework fx = new SupportedFramework (target);
-
- fx.DisplayName = path.FileNameWithoutExtension;
-
using (var reader = XmlReader.Create (path)) {
if (!reader.ReadToDescendant ("Framework"))
throw new Exception ("Missing Framework element");
-
- if (!reader.HasAttributes)
- throw new Exception ("Framework element does not contain any attributes");
-
- while (reader.MoveToNextAttribute ()) {
- switch (reader.Name) {
- case "MaximumVersion":
- fx.MaximumVersion = ParseVersion (reader.Value, NoMaximumVersion);
- break;
- case "MinimumVersion":
- fx.MinimumVersion = ParseVersion (reader.Value, NoMinumumVersion);
- break;
- case "Profile":
- fx.Profile = reader.Value;
- break;
- case "Identifier":
- fx.Identifier = reader.Value;
- break;
- case "MinimumVersionDisplayName":
- fx.MinimumVersionDisplayName = reader.Value;
- break;
- case "DisplayName":
- fx.DisplayName = reader.Value;
- break;
- case "MonoSpecificVersion":
- fx.MonoSpecificVersion = reader.Value;
- break;
- case "MonoSpecificVersionDisplayName":
- fx.MonoSpecificVersionDisplayName = reader.Value;
- break;
- }
+ var fx = LoadFromAttributes (reader);
+ if (string.IsNullOrEmpty (fx.DisplayName)) {
+ fx.DisplayName = path.FileNameWithoutExtension;
+ }
+ return fx;
+ }
+
+ }
+ internal static SupportedFramework LoadFromAttributes (XmlReader reader)
+ {
+ var fx = new SupportedFramework ();
+ if (!reader.HasAttributes)
+ throw new Exception ("Framework element does not contain any attributes");
+
+ while (reader.MoveToNextAttribute ()) {
+ switch (reader.Name) {
+ case "MaximumVersion":
+ fx.MaximumVersion = ParseVersion (reader.Value, NoMaximumVersion);
+ break;
+ case "MinimumVersion":
+ fx.MinimumVersion = ParseVersion (reader.Value, NoMinimumVersion);
+ break;
+ case "Profile":
+ fx.Profile = reader.Value;
+ break;
+ case "Identifier":
+ fx.Identifier = reader.Value;
+ break;
+ case "MinimumVersionDisplayName":
+ fx.MinimumVersionDisplayName = reader.Value;
+ break;
+ case "DisplayName":
+ fx.DisplayName = reader.Value;
+ break;
+ case "MonoSpecificVersion":
+ fx.MonoSpecificVersion = reader.Value;
+ break;
+ case "MonoSpecificVersionDisplayName":
+ fx.MonoSpecificVersionDisplayName = reader.Value;
+ break;
}
}
if (string.IsNullOrEmpty (fx.Identifier))
throw new Exception ("Framework element did not specify an Identifier attribute");
-
+
return fx;
}
+ internal void SaveAsElement (XmlWriter writer)
+ {
+ writer.WriteStartElement ("SupportedFramework");
+ if (MaximumVersion != NoMaximumVersion) {
+ writer.WriteAttributeString ("MaximumVersion", MaximumVersion.ToString ());
+ }
+ if (MinimumVersion != NoMinimumVersion) {
+ writer.WriteAttributeString ("MinimumVersion", MinimumVersion.ToString ());
+ }
+ WriteNonEmptyAttribute ("Profile", Profile);
+ WriteNonEmptyAttribute ("Identifier", Identifier);
+ WriteNonEmptyAttribute ("MinimumVersionDisplayName", MinimumVersionDisplayName);
+ WriteNonEmptyAttribute ("MonoSpecificVersion", MonoSpecificVersion);
+ WriteNonEmptyAttribute ("MonoSpecificVersionDisplayName", MonoSpecificVersionDisplayName);
+
+ writer.WriteEndElement ();
+
+ void WriteNonEmptyAttribute (string name, string val)
+ {
+ if (!string.IsNullOrEmpty (val)) {
+ writer.WriteAttributeString (name, val);
+ }
+ }
+ }
+
public override int GetHashCode ()
{
return DisplayName != null ? DisplayName.GetHashCode () : 0;
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs
index c9c6a32d5b..9c78def14b 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs
@@ -29,9 +29,7 @@ using System;
using System.IO;
using System.Collections.Generic;
-using Mono.Addins;
using Mono.PkgConfig;
-using MonoDevelop.Core.AddIns;
using MonoDevelop.Core.Serialization;
using System.Reflection;
@@ -46,7 +44,7 @@ namespace MonoDevelop.Core.Assemblies
List<SupportedFramework> supportedFrameworks = new List<SupportedFramework> ();
internal bool RelationsBuilt;
-
+
string corlibVersion;
public static TargetFramework Default {
@@ -63,9 +61,9 @@ namespace MonoDevelop.Core.Assemblies
this.name = id.Profile == null
? string.Format ("{0} {1}", id.Identifier, id.Version)
: string.Format ("{0} {1} {2} Profile", id.Identifier, id.Version, id.Profile);
- Assemblies = new AssemblyInfo[0];
+ Assemblies = new AssemblyInfo [0];
}
-
+
public string Name {
get {
if (string.IsNullOrEmpty (name)) {
@@ -76,19 +74,19 @@ namespace MonoDevelop.Core.Assemblies
return name;
}
}
-
+
public TargetFrameworkMoniker Id {
get {
return id;
}
}
- [Obsolete("It is no longer possible to define a hidden framework")]
+ [Obsolete ("It is no longer possible to define a hidden framework")]
public bool Hidden { get; } = false;
-
- [Obsolete("This value is no longer meaningful")]
+
+ [Obsolete ("This value is no longer meaningful")]
public ClrVersion ClrVersion { get; } = ClrVersion.Net_4_0;
-
+
static bool ProfileMatchesPattern (string profile, string pattern)
{
if (string.IsNullOrEmpty (pattern))
@@ -163,12 +161,12 @@ namespace MonoDevelop.Core.Assemblies
return fx.Id.Identifier == id.Identifier && new Version (fx.Id.Version).CompareTo (new Version (id.Version)) <= 0;
}
-
+
internal string GetCorlibVersion ()
{
if (corlibVersion != null)
return corlibVersion;
-
+
foreach (AssemblyInfo asm in Assemblies) {
if (asm.Name == "mscorlib")
return corlibVersion = asm.Version;
@@ -185,121 +183,102 @@ namespace MonoDevelop.Core.Assemblies
get { return includedFrameworks; }
}
- #pragma warning disable 649
+#pragma warning disable 649
string includesFramework;
- #pragma warning restore 649
+#pragma warning restore 649
internal TargetFrameworkMoniker GetIncludesFramework ()
{
if (string.IsNullOrEmpty (includesFramework))
return null;
- string version = includesFramework[0] == 'v'?
+ string version = includesFramework [0] == 'v' ?
includesFramework.Substring (1) : includesFramework;
if (version.Length == 0)
throw new InvalidOperationException ("Invalid include version in framework " + id);
-
- return new TargetFrameworkMoniker (id.Identifier, version);
+
+ return new TargetFrameworkMoniker (id.Identifier, version);
}
-
+
public List<SupportedFramework> SupportedFrameworks {
get { return supportedFrameworks; }
}
-
- internal AssemblyInfo[] Assemblies {
+
+ internal AssemblyInfo [] Assemblies {
get;
set;
}
-
+
+ internal string FrameworkAssembliesDirectory { get; set; }
+
public override string ToString ()
{
return $"[TargetFramework: Name={Name}, Id={Id}]";
}
-
+
public static TargetFramework FromFrameworkDirectory (TargetFrameworkMoniker moniker, FilePath dir)
{
- var fxList = dir.Combine ("RedistList", "FrameworkList.xml");
- if (!File.Exists (fxList))
+ var fxListFile = dir.Combine ("RedistList", "FrameworkList.xml");
+ var fxListInfo = new FileInfo (fxListFile);
+ if (!fxListInfo.Exists)
return null;
-
- var fx = new TargetFramework (moniker);
-
- using (var reader = System.Xml.XmlReader.Create (fxList)) {
- if (!reader.ReadToDescendant ("FileList"))
- throw new Exception ("Missing FileList element");
-
- //not sure what this is for
- //if (reader.MoveToAttribute ("Redist") && reader.ReadAttributeValue ())
- // redist = reader.ReadContentAsString ();
-
- if (reader.MoveToAttribute ("Name") && reader.ReadAttributeValue ())
- fx.name = reader.ReadContentAsString ();
-
- if (reader.MoveToAttribute ("IncludeFramework") && reader.ReadAttributeValue ()) {
- string include = reader.ReadContentAsString ();
- if (!string.IsNullOrEmpty (include))
- fx.includesFramework = include;
- }
-
- //this is a Mono-specific extension
- if (reader.MoveToAttribute ("TargetFrameworkDirectory") && reader.ReadAttributeValue ()) {
- string targetDir = reader.ReadContentAsString ();
- if (!string.IsNullOrEmpty (targetDir)) {
- targetDir = targetDir.Replace ('\\', System.IO.Path.DirectorySeparatorChar);
- dir = fxList.ParentDirectory.Combine (targetDir).FullPath;
- }
+
+ var fxCacheDir = UserProfile.Current.CacheDir.Combine ("FrameworkInfo");
+
+ var cacheKey = moniker.Identifier + "_" + moniker.Version;
+ if (!string.IsNullOrEmpty (moniker.Profile)) {
+ cacheKey += "_" + moniker.Profile;
+ }
+
+ FrameworkInfo fxInfo;
+
+ var cachedListFile = fxCacheDir.Combine (cacheKey + ".xml");
+ var cachedListInfo = new FileInfo (cachedListFile);
+ if (cachedListInfo.Exists && cachedListInfo.LastWriteTime == fxListInfo.LastWriteTime) {
+ fxInfo = FrameworkInfo.Load (moniker, cachedListFile);
+ } else {
+ fxInfo = FrameworkInfo.Load (moniker, fxListFile);
+ var supportedFrameworksDir = dir.Combine ("SupportedFrameworks");
+ if (Directory.Exists (supportedFrameworksDir)) {
+ foreach (var sfx in Directory.EnumerateFiles (supportedFrameworksDir))
+ fxInfo.SupportedFrameworks.Add (SupportedFramework.Load (sfx));
}
-
- var assemblies = new List<AssemblyInfo> ();
- if (reader.ReadToFollowing ("File")) {
- do {
- var ainfo = new AssemblyInfo ();
- assemblies.Add (ainfo);
- if (reader.MoveToAttribute ("AssemblyName") && reader.ReadAttributeValue ())
- ainfo.Name = reader.ReadContentAsString ();
- if (string.IsNullOrEmpty (ainfo.Name))
- throw new Exception ("Missing AssemblyName attribute");
- if (reader.MoveToAttribute ("Version") && reader.ReadAttributeValue ())
- ainfo.Version = reader.ReadContentAsString ();
- if (reader.MoveToAttribute ("PublicKeyToken") && reader.ReadAttributeValue ())
- ainfo.PublicKeyToken = reader.ReadContentAsString ();
- if (reader.MoveToAttribute ("Culture") && reader.ReadAttributeValue ())
- ainfo.Culture = reader.ReadContentAsString ();
- if (reader.MoveToAttribute ("ProcessorArchitecture") && reader.ReadAttributeValue ())
- ainfo.ProcessorArchitecture = (ProcessorArchitecture)
- Enum.Parse (typeof (ProcessorArchitecture), reader.ReadContentAsString (), true);
- if (reader.MoveToAttribute ("InGac") && reader.ReadAttributeValue ())
- ainfo.InGac = reader.ReadContentAsBoolean ();
- } while (reader.ReadToFollowing ("File"));
- } else if (Directory.Exists (dir)) {
-
- foreach (var f in Directory.EnumerateFiles (dir, "*.dll")) {
- try {
- var an = SystemAssemblyService.GetAssemblyNameObj (dir.Combine (f));
- var ainfo = new AssemblyInfo ();
- ainfo.Update (an);
- assemblies.Add (ainfo);
- } catch (BadImageFormatException ex) {
- LoggingService.LogError ("Invalid assembly in framework '{0}': {1}{2}{3}", fx.Id, f, Environment.NewLine, ex.ToString ());
- } catch (Exception ex) {
- LoggingService.LogError ("Error reading assembly '{0}' in framework '{1}':{2}{3}",
- f, fx.Id, Environment.NewLine, ex.ToString ());
- }
- }
+ if (fxInfo.Assemblies.Count == 0) {
+ fxInfo.Assemblies = ScanAssemblyDirectory (moniker, fxInfo.TargetFrameworkDirectory);
}
-
- fx.Assemblies = assemblies.ToArray ();
+ Directory.CreateDirectory (fxCacheDir);
+ fxInfo.Save (cachedListFile);
+ File.SetLastWriteTime (cachedListFile, fxListInfo.LastWriteTime);
}
-
- var supportedFrameworksDir = dir.Combine ("SupportedFrameworks");
- if (Directory.Exists (supportedFrameworksDir)) {
- foreach (var sfx in Directory.GetFiles (supportedFrameworksDir))
- fx.SupportedFrameworks.Add (SupportedFramework.Load (fx, sfx));
+
+ return new TargetFramework (moniker) {
+ name = fxInfo.Name,
+ includesFramework = fxInfo.IncludeFramework,
+ Assemblies = fxInfo.Assemblies.ToArray (),
+ supportedFrameworks = fxInfo.SupportedFrameworks,
+ FrameworkAssembliesDirectory = fxInfo.TargetFrameworkDirectory
+ };
+ }
+
+ static List<AssemblyInfo> ScanAssemblyDirectory (TargetFrameworkMoniker tfm, FilePath dir)
+ {
+ var assemblies = new List<AssemblyInfo> ();
+ foreach (var f in Directory.EnumerateFiles (dir, "*.dll")) {
+ try {
+ var an = SystemAssemblyService.GetAssemblyNameObj (dir.Combine (f));
+ var ainfo = new AssemblyInfo ();
+ ainfo.Update (an);
+ assemblies.Add (ainfo);
+ } catch (BadImageFormatException ex) {
+ LoggingService.LogError ("Invalid assembly in framework '{0}': {1}{2}{3}", tfm, f, Environment.NewLine, ex.ToString ());
+ } catch (Exception ex) {
+ LoggingService.LogError ("Error reading assembly '{0}' in framework '{1}':{2}{3}",
+ f, tfm, Environment.NewLine, ex.ToString ());
+ }
}
-
- return fx;
+ return assemblies;
}
}
-
+
class AssemblyInfo
{
[ItemProperty ("name")]
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkBackend.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkBackend.cs
index 1e93638b32..9c69d7e490 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkBackend.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkBackend.cs
@@ -27,6 +27,7 @@
using System;
using System.IO;
using System.Collections.Generic;
+using System.Linq;
namespace MonoDevelop.Core.Assemblies
{
@@ -46,32 +47,41 @@ namespace MonoDevelop.Core.Assemblies
bool? isInstalled;
public virtual bool IsInstalled {
get {
- if (isInstalled != null)
- return isInstalled.Value;
-
- foreach (string dir in GetFrameworkFolders ()) {
- if (Directory.Exists (dir)) {
- string manifest = Path.Combine (dir, "RedistList", "FrameworkList.xml");
- if (File.Exists (manifest)) {
- isInstalled = true;
- return true;
- }
- if (framework.Assemblies.Length > 0) {
- string firstAsm = Path.Combine (dir, framework.Assemblies [0].Name) + ".dll";
- if (File.Exists (firstAsm)) {
- isInstalled = true;
- return true;
- }
- }
- }
+ if (isInstalled == null)
+ isInstalled = GetFrameworkFolders ().Any ();
+ return isInstalled.Value;
+ }
+ internal set {
+ isInstalled = value;
+ }
+ }
+
+ internal string ReferenceAssembliesFolder { get; set; }
+
+ protected virtual string OnGetReferenceAssembliesFolder ()
+ {
+ var fxDir = framework.Id.GetAssemblyDirectoryName ();
+ foreach (var rootDir in runtime.GetReferenceFrameworkDirectories ()) {
+ var dir = rootDir.Combine (fxDir);
+ var frameworkList = dir.Combine ("RedistList", "FrameworkList.xml");
+ if (File.Exists (frameworkList))
+ return dir;
+ }
+ return null;
+ }
+
+ public virtual IEnumerable<string> GetFrameworkFolders ()
+ {
+ if (!string.IsNullOrEmpty (ReferenceAssembliesFolder)) {
+ yield return ReferenceAssembliesFolder;
+ } else {
+ ReferenceAssembliesFolder = OnGetReferenceAssembliesFolder () ?? "";
+ if (!string.IsNullOrEmpty (ReferenceAssembliesFolder)) {
+ yield return ReferenceAssembliesFolder;
}
- isInstalled = false;
- return false;
}
}
- public abstract IEnumerable<string> GetFrameworkFolders ();
-
public virtual Dictionary<string, string> GetToolsEnvironmentVariables ()
{
return new Dictionary<string,string> ();
@@ -151,7 +161,7 @@ namespace MonoDevelop.Core.Assemblies
public override IEnumerable<string> GetFrameworkFolders ()
{
- return null;
+ yield break;
}
public override bool IsInstalled {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs
index dd5a651d23..6ec1e3b665 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetRuntime.cs
@@ -27,21 +27,16 @@
// THE SOFTWARE.
using System;
-using System.Threading;
-using System.IO;
-using System.Xml;
-using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Reflection;
-using System.Collections.Specialized;
-using MonoDevelop.Core.Execution;
-using MonoDevelop.Core.AddIns;
-using MonoDevelop.Core.Serialization;
+using System.IO;
+using System.Linq;
+using System.Threading;
using Mono.Addins;
-using Mono.PkgConfig;
+using MonoDevelop.Core.AddIns;
+using MonoDevelop.Core.Execution;
using MonoDevelop.Core.Instrumentation;
-using System.Linq;
+using System.Runtime.CompilerServices;
namespace MonoDevelop.Core.Assemblies
{
@@ -244,19 +239,23 @@ namespace MonoDevelop.Core.Assemblies
protected virtual void ConvertAssemblyProcessStartInfo (ProcessStartInfo pinfo)
{
}
-
+
+ NotSupportedFrameworkBackend NotSupportedBackend = new NotSupportedFrameworkBackend ();
+
protected TargetFrameworkBackend GetBackend (TargetFramework fx)
{
EnsureInitialized ();
- lock (frameworkBackends) {
- TargetFrameworkBackend backend;
- if (frameworkBackends.TryGetValue (fx.Id, out backend))
- return backend;
- backend = CreateBackend (fx) ?? new NotSupportedFrameworkBackend ();
- backend.Initialize (this, fx);
- frameworkBackends[fx.Id] = backend;
+ if (frameworkBackends.TryGetValue (fx.Id, out TargetFrameworkBackend backend))
return backend;
- }
+ return NotSupportedBackend;
+ }
+
+ TargetFrameworkBackend CreateAndInitializeBackend (TargetFramework fx)
+ {
+ var backend = CreateBackend (fx);
+ backend.Initialize (this, fx);
+ frameworkBackends [fx.Id] = backend;
+ return backend;
}
protected virtual TargetFrameworkBackend CreateBackend (TargetFramework fx)
@@ -385,9 +384,19 @@ namespace MonoDevelop.Core.Assemblies
}
}
}
-
+
+ //runtimes can't get deinitialized, so add an inlinable fast path
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void EnsureInitialized ()
{
+ if (initialized) {
+ return;
+ }
+ EnsureInitializedSlow ();
+ }
+
+ void EnsureInitializedSlow()
+ {
lock (initLock) {
if (!initialized && !initializing) {
if (!backgroundInitialize) {
@@ -542,20 +551,27 @@ namespace MonoDevelop.Core.Assemblies
void CreateFrameworks ()
{
var frameworks = new HashSet<TargetFrameworkMoniker> ();
-
- foreach (TargetFramework fx in Runtime.SystemAssemblyService.GetKnownFrameworks ()) {
- // A framework is installed if the assemblies directory exists and the first
- // assembly of the list exists.
- if (frameworks.Add (fx.Id) && IsInstalled (fx)) {
- timer.Trace ("Registering assemblies for framework " + fx.Id);
+
+ //register custom frameworks first. they may have been found by another runtime
+ //already, but we want to use this runtime's version so path info is correct
+ foreach (TargetFramework fx in CustomFrameworks) {
+ if (frameworks.Add (fx.Id)) {
+ //if the framework was discovered in this runtime, we know it's installed
+ var backend = CreateAndInitializeBackend (fx);
+ backend.IsInstalled = true;
+ backend.ReferenceAssembliesFolder = fx.FrameworkAssembliesDirectory;
RegisterSystemAssemblies (fx);
}
}
-
- foreach (TargetFramework fx in CustomFrameworks) {
- if (frameworks.Add (fx.Id) && IsInstalled (fx)) {
- timer.Trace ("Registering assemblies for framework " + fx.Id);
- RegisterSystemAssemblies (fx);
+
+ foreach (TargetFramework fx in Runtime.SystemAssemblyService.GetKnownFrameworks ()) {
+ // A framework is installed if the assemblies directory exists and the first
+ // assembly of the list exists.
+ if (frameworks.Add (fx.Id)) {
+ var backend = CreateAndInitializeBackend (fx);
+ if (backend.IsInstalled) {
+ RegisterSystemAssemblies (fx);
+ }
}
}
}
@@ -567,45 +583,18 @@ namespace MonoDevelop.Core.Assemblies
void RegisterSystemAssemblies (TargetFramework fx)
{
- Dictionary<string,List<SystemAssembly>> assemblies = new Dictionary<string, List<SystemAssembly>> ();
- Dictionary<string,SystemPackage> packs = new Dictionary<string, SystemPackage> ();
-
- IEnumerable<string> dirs = GetFrameworkFolders (fx);
-
+ var assemblies = new List<SystemAssembly> ();
+ var package = new SystemPackage ();
foreach (AssemblyInfo assembly in fx.Assemblies) {
- foreach (string dir in dirs) {
- string file = Path.Combine (dir, assembly.Name) + ".dll";
- if (File.Exists (file)) {
- if (assembly.Version == null && IsRunning) {
- try {
- AssemblyName aname = SystemAssemblyService.GetAssemblyNameObj (file);
- assembly.Update (aname);
- } catch {
- // If something goes wrong when getting the name, just ignore the assembly
- }
- }
- string pkg = assembly.Package ?? string.Empty;
- SystemPackage package;
- if (!packs.TryGetValue (pkg, out package)) {
- packs [pkg] = package = new SystemPackage ();
- assemblies [pkg] = new List<SystemAssembly> ();
- }
- List<SystemAssembly> list = assemblies [pkg];
- list.Add (assemblyContext.AddAssembly (file, assembly, package));
- break;
- }
- }
- }
-
- foreach (string pkg in packs.Keys) {
- SystemPackage package = packs [pkg];
- List<SystemAssembly> list = assemblies [pkg];
- SystemPackageInfo info = GetFrameworkPackageInfo (fx, pkg);
- if (!info.IsCorePackage)
- corePackages.Add (info.Name);
- package.Initialize (info, list.ToArray (), false);
- assemblyContext.InternalAddPackage (package);
+ var file = Path.Combine (fx.FrameworkAssembliesDirectory, assembly.Name + ".dll");
+ assemblies.Add (assemblyContext.AddAssembly (file, assembly, package));
}
+
+ SystemPackageInfo info = GetFrameworkPackageInfo (fx, "");
+ package.Initialize (info, assemblies, false);
+ if (!info.IsCorePackage)
+ corePackages.Add (info.Name);
+ assemblyContext.InternalAddPackage (package);
}
protected virtual SystemPackageInfo GetFrameworkPackageInfo (TargetFramework fx, string packageName)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
index 4692af099b..ee14abcc69 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
@@ -763,6 +763,7 @@
<Compile Include="MonoDevelop.Core\ObjectPool.cs" />
<Compile Include="MonoDevelop.Core\SharedPools.cs" />
<Compile Include="MonoDevelop.Core.Collections\LookupTable.cs" />
+ <Compile Include="MonoDevelop.Core.Assemblies\FrameworkInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Makefile.am" />
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/PortableRuntimeSelectorDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/PortableRuntimeSelectorDialog.cs
index d56604b2cb..8d7bb8fa2d 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/PortableRuntimeSelectorDialog.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects.OptionPanels/PortableRuntimeSelectorDialog.cs
@@ -59,13 +59,11 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
{
public readonly string Name;
public readonly SupportedFramework Framework;
- public readonly List<TargetFramework> Targets;
public OptionComboItem (string name, SupportedFramework sfx)
{
this.Name = name;
this.Framework = sfx;
- this.Targets = new List<TargetFramework> ();
}
}
@@ -138,8 +136,6 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
item = new OptionComboItem (label, sfx);
dict.Add (label, item);
}
-
- item.Targets.Add (sfx.TargetFramework);
}
combo.Items = dict.Values.ToList ();
@@ -277,7 +273,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
void AddTopSelectorCombo ()
{
- var model = new ListStore (new Type[] { typeof (string), typeof (object) });
+ var model = new ListStore (new Type[] { typeof (string) });
var renderer = new CellRendererText ();
var combo = selectorCombo = new ComboBox (model);
@@ -337,7 +333,7 @@ namespace MonoDevelop.Ide.Projects.OptionPanels
if (hasOtherVersions && string.IsNullOrEmpty (sfx.MonoSpecificVersionDisplayName))
label += " or later";
- model.AppendValues (label, item.Targets);
+ model.AppendValues (label);
}
option.Combo = new ComboBox (model);