diff --git a/main/external/fsharpbinding/paket.dependencies b/main/external/fsharpbinding/paket.dependencies
index 0fa75c3a9f3..1b3e2d53ee5 100644
--- a/main/external/fsharpbinding/paket.dependencies
+++ b/main/external/fsharpbinding/paket.dependencies
@@ -1,6 +1,6 @@
version 5.201.1
framework: net472
-source https://nuget.org/api/v2/
+source https://api.nuget.org/v3/index.json
nuget ExtCore framework: >= net40
nuget FSharp.Compiler.Service 31.0.0
diff --git a/main/external/fsharpbinding/paket.lock b/main/external/fsharpbinding/paket.lock
index 817a6a8ded3..b099144eba0 100644
--- a/main/external/fsharpbinding/paket.lock
+++ b/main/external/fsharpbinding/paket.lock
@@ -1,6 +1,6 @@
RESTRICTION: == net472
NUGET
- remote: https://www.nuget.org/api/v2
+ remote: https://api.nuget.org/v3/index.json
ExtCore (0.8.46)
FAKE (5.8.4)
Fantomas (3.0.0-beta-002)
diff --git a/main/src/addins/MonoDevelop.AspNetCore/Properties/MonoDevelop.AspNetCore.addin.xml b/main/src/addins/MonoDevelop.AspNetCore/Properties/MonoDevelop.AspNetCore.addin.xml
index 65267a36850..6df895b7001 100644
--- a/main/src/addins/MonoDevelop.AspNetCore/Properties/MonoDevelop.AspNetCore.addin.xml
+++ b/main/src/addins/MonoDevelop.AspNetCore/Properties/MonoDevelop.AspNetCore.addin.xml
@@ -83,6 +83,351 @@
For example, .NET Core 1.1 SDK does not have a Razor template so having the 1.1 templates first
would cause the Razor template to be last in the New Project dialog if both 1.1 and 2.x templates
are available. -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
GetTags (Type type)
{
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Templating/DotNetCoreProjectTemplateWizard.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Templating/DotNetCoreProjectTemplateWizard.cs
index 928ed14b8bf..e12599a1cdb 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Templating/DotNetCoreProjectTemplateWizard.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore.Templating/DotNetCoreProjectTemplateWizard.cs
@@ -33,6 +33,7 @@ namespace MonoDevelop.DotNetCore.Templating
{
class DotNetCoreProjectTemplateWizard : TemplateWizard
{
+ const string defaultParameterNetCore60 = "UseNetCore60";
const string defaultParameterNetCore50 = "UseNetCore50";
const string defaultParameterNetCore30 = "UseNetCore30";
const string defaultParameterNetCore20 = "UseNetCore20";
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs
index 6726991945c..29896551502 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreProjectSupportedTargetFrameworks.cs
@@ -96,7 +96,7 @@ static IEnumerable GetKnownNetCoreAppFrameworks ()
public static IEnumerable GetNetStandardTargetFrameworks ()
{
- if (DotNetCoreRuntime.IsNetCore30Installed () || MonoRuntimeInfoExtensions.CurrentRuntimeVersion.SupportsNetStandard21 ())
+ if (DotNetCoreRuntime.IsNetCore3xOrHigherInstalled () || MonoRuntimeInfoExtensions.CurrentRuntimeVersion.SupportsNetStandard21 ())
yield return CreateTargetFramework (".NETStandard", "2.1");
if (DotNetCoreRuntime.IsNetCore2xInstalled () || MonoRuntimeInfoExtensions.CurrentRuntimeVersion.SupportsNetStandard20 ())
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRuntime.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRuntime.cs
index a8ff897af09..b7e24b927d5 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRuntime.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreRuntime.cs
@@ -25,7 +25,7 @@
// THE SOFTWARE.
using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using MonoDevelop.Core;
@@ -124,6 +124,10 @@ internal static bool IsNetCore30Installed ()
return Versions.Any (version => version.Major == 3 && version.Minor == 0);
}
+ internal static bool IsNetCore3xOrHigherInstalled ()
+ {
+ return Versions.Any (version => version.Major >= 3);
+ }
///
/// Used by unit tests to fake having different .NET Core sdks installed.
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreVersion.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreVersion.cs
index 5cb247939ce..d65de6eef6b 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreVersion.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/DotNetCoreVersion.cs
@@ -34,12 +34,14 @@ namespace MonoDevelop.DotNetCore
{
class DotNetCoreVersion : IEquatable, IComparable, IComparable
{
- internal static readonly DotNetCoreVersion MinimumSupportedSdkVersion = new DotNetCoreVersion (2, 1, 602);
+ internal static readonly DotNetCoreVersion MinimumSupportedSdkVersion = new DotNetCoreVersion (2, 1, 30);
internal static readonly DotNetCoreVersion MinimumSupportedSdkVersion22 = new DotNetCoreVersion (2, 2, 202);
internal static readonly DotNetCoreVersion MinimumSupportedSdkVersion30 = new DotNetCoreVersion (3, 0, 100) {
ReleaseLabel = "preview3-010431",
IsPrerelease = true
};
+ internal static readonly DotNetCoreVersion MinimumSupportedSdkVersion50 = new DotNetCoreVersion (5, 0, 400);
+ internal static readonly DotNetCoreVersion MinimumSupportedSdkVersion60 = new DotNetCoreVersion (6, 0, 6);
internal DotNetCoreVersion (int major, int minor, int patch)
: this (new Version (major, minor, patch))
@@ -244,6 +246,16 @@ public static bool IsSdkSupported (DotNetCoreVersion version)
return version >= MinimumSupportedSdkVersion30;
}
+ if (version.Major == 5) {
+ return version >= MinimumSupportedSdkVersion50;
+ }
+
+ if (version.Major == 6) {
+ return version >= MinimumSupportedSdkVersion60;
+ }
+
+
+
return false;
}
}
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/MonoRuntimeInfoExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/MonoRuntimeInfoExtensions.cs
index 2e9a3999082..b97fc2e7dbb 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/MonoRuntimeInfoExtensions.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/MonoRuntimeInfoExtensions.cs
@@ -32,8 +32,10 @@ namespace MonoDevelop.DotNetCore
static class MonoRuntimeInfoExtensions
{
static readonly Version MonoVersion5_4 = new Version (5, 4, 0);
+ static readonly Version MonoVersion6_4 = new Version (6, 4, 0);
static readonly Version DotNetCore2_1 = new Version (2, 1);
+
internal static Version CurrentRuntimeVersion { get; set; } = MonoRuntimeInfo.FromCurrentRuntime ()?.RuntimeVersion ?? new Version ();
public static bool SupportsNetStandard20 (this Version monoVersion)
@@ -43,8 +45,8 @@ public static bool SupportsNetStandard20 (this Version monoVersion)
public static bool SupportsNetStandard21 (this Version monoVersion)
{
- //FIXME: update this: which Mono version will support .NET Standadrd 2.1
- return false;
+ // ref https://www.mono-project.com/docs/about-mono/releases/6.4.0/
+ return monoVersion >= MonoVersion6_4; ;
}
public static bool SupportsNetCore (this Version monoVersion, string netCoreVersion)
diff --git a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs
index 6f66e358944..a953efbd90d 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs
+++ b/main/src/addins/MonoDevelop.DotNetCore/MonoDevelop.DotNetCore/TargetFrameworkExtensions.cs
@@ -100,9 +100,9 @@ public static string GetDisplayName (this TargetFramework framework)
if (framework.IsNetCoreApp ()) {
// Display shortened framework names for .net5.0 and above in NewProject dialog
if (version.Major >= 5) {
- return string.Format (".net {0}", framework.Id.Version);
+ return string.Format (".net{0}", framework.Id.Version);
} else {
- return string.Format (".NET Core {0}", framework.Id.Version);
+ return string.Format (".netcoreapp{0}", framework.Id.Version);
}
}
diff --git a/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml b/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml
index a7b19e978ff..feb072c6c8f 100644
--- a/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml
+++ b/main/src/addins/MonoDevelop.DotNetCore/Properties/MonoDevelop.DotNetCore.addin.xml
@@ -260,6 +260,86 @@
category="netcore/app/general"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -1621,4 +2195,5 @@
+
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SystemAssemblyService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SystemAssemblyService.cs
index 5eb2a9b08d5..663135e0e8e 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SystemAssemblyService.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/SystemAssemblyService.cs
@@ -182,17 +182,19 @@ public TargetFramework GetTargetFramework (TargetFrameworkMoniker id)
{
TargetFramework fx;
if (frameworks.TryGetValue (id, out fx))
- return fx;
+ return fx; // found on first check against known .NETFrameworks
- LoggingService.LogDebug ("Unknown TargetFramework '{0}' is being requested from SystemAssemblyService, ensuring runtimes initialized and trying again", id);
+ // otherwise, ensure runtimes have been initialised, then try again
foreach (var r in runtimes)
r.EnsureInitialized ();
if (frameworks.TryGetValue (id, out fx))
return fx;
-
- LoggingService.LogWarning ("Unknown TargetFramework '{0}' is being requested from SystemAssemblyService, returning empty TargetFramework", id);
- UpdateFrameworks (new [] { new TargetFramework (id) });
+ // still not found - don't warn, but add .NETCoreApp and .NETStandard frameworks via 'UpdateFrameworks'
+ // LoggingService.LogWarning ("Unknown TargetFramework '{0}' is being requested from SystemAssemblyService, returning empty TargetFramework", id);
+
+ var tf = new TargetFramework (id);
+ UpdateFrameworks (new [] {tf});
return frameworks [id];
}
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 92f979c70fd..7c1f30fc0c3 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFramework.cs
@@ -61,15 +61,34 @@ internal TargetFramework (TargetFrameworkMoniker id)
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);
+
+ if (id.Identifier == ".NETCoreApp") {
+ int i = id.Version.IndexOf ('.');
+ int majorVersion = int.Parse (id.Version.Substring (0, i));
+ if (majorVersion >= 5) {
+ this.name = id.Profile == null
+ ? string.Format (".net{0}", id.Version)
+ : string.Format (".net{0} {1}", id.Version, id.Profile);
+ }
+ }
Assemblies = new AssemblyInfo [0];
}
public string Name {
get {
if (string.IsNullOrEmpty (name)) {
- return string.IsNullOrEmpty (id.Profile)
+ name = id.Profile == null
? string.Format ("{0} {1}", id.Identifier, id.Version)
- : string.Format ("{0} {1} ({2})", id.Identifier, id.Version, id.Profile);
+ : string.Format ("{0} {1} {2} Profile", id.Identifier, id.Version, id.Profile);
+ }
+ if (id.Identifier == ".NETCoreApp") {
+ int i = id.Version.IndexOf ('.');
+ int majorVersion = int.Parse (id.Version.Substring (0, i));
+ if (majorVersion >= 5) {
+ name = id.Profile == null
+ ? string.Format (".net{0}", id.Version)
+ : string.Format (".net{0} {1}", id.Version, id.Profile);
+ }
}
return name;
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
index 2ff1f17498d..56689ff4e1b 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.csproj
@@ -629,7 +629,6 @@
-
@@ -747,7 +746,6 @@
-
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IntrinsicFunctions.Extensions.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IntrinsicFunctions.Extensions.cs
deleted file mode 100644
index 68e79fa7e24..00000000000
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IntrinsicFunctions.Extensions.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// IntrinsicFunctions.Extensions.cs
-//
-// Author:
-// Marius Ungureanu
-//
-// Copyright (c) 2019 Microsoft Inc.
-//
-// 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;
-namespace Microsoft.Build.Evaluation
-{
- internal static partial class IntrinsicFunctions
- {
- // Similar to https://github.com/microsoft/msbuild/pull/4731
- // This avoids creating a string copy for the purpose of evaluation in metadata items.
- internal static string Copy (string value) => value;
- }
-}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IntrinsicFunctions.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IntrinsicFunctions.cs
deleted file mode 100644
index ef0da6883ca..00000000000
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/IntrinsicFunctions.cs
+++ /dev/null
@@ -1,513 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-//-----------------------------------------------------------------------
-//
-// Definition of functions which can be accessed from MSBuild files.
-//-----------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Runtime.InteropServices;
-using System.Text.RegularExpressions;
-
-using Microsoft.Build.Internal;
-using Microsoft.Build.Shared;
-using Microsoft.Win32;
-
-using MonoDevelop.Core;
-using MonoDevelop.Core.Assemblies;
-
-
-namespace Microsoft.Build.Evaluation
-{
- ///
- /// The Intrinsic class provides static methods that can be accessed from MSBuild's
- /// property functions using $([MSBuild]::Function(x,y))
- ///
- internal static partial class IntrinsicFunctions
- {
- ///
- /// Add two doubles
- ///
- internal static double Add (double a, double b)
- {
- return a + b;
- }
-
- ///
- /// Add two longs
- ///
- internal static long Add (long a, long b)
- {
- return a + b;
- }
-
- ///
- /// Subtract two doubles
- ///
- internal static double Subtract (double a, double b)
- {
- return a - b;
- }
-
- ///
- /// Subtract two longs
- ///
- internal static long Subtract (long a, long b)
- {
- return a - b;
- }
-
- ///
- /// Multiply two doubles
- ///
- internal static double Multiply (double a, double b)
- {
- return a * b;
- }
-
- ///
- /// Multiply two longs
- ///
- internal static long Multiply (long a, long b)
- {
- return a * b;
- }
-
- ///
- /// Divide two doubles
- ///
- internal static double Divide (double a, double b)
- {
- return a / b;
- }
-
- ///
- /// Divide two longs
- ///
- internal static long Divide (long a, long b)
- {
- return a / b;
- }
-
- ///
- /// Modulo two doubles
- ///
- internal static double Modulo (double a, double b)
- {
- return a % b;
- }
-
- ///
- /// Modulo two longs
- ///
- internal static long Modulo (long a, long b)
- {
- return a % b;
- }
-
- ///
- /// Escape the string according to MSBuild's escaping rules
- ///
- internal static string Escape (string unescaped)
- {
- return EscapingUtilities.Escape (unescaped);
- }
-
- ///
- /// Unescape the string according to MSBuild's escaping rules
- ///
- internal static string Unescape (string escaped)
- {
- return EscapingUtilities.UnescapeAll (escaped);
- }
-
- ///
- /// Perform a bitwise OR on the first and second (first | second)
- ///
- internal static int BitwiseOr (int first, int second)
- {
- return first | second;
- }
-
- ///
- /// Perform a bitwise AND on the first and second (first & second)
- ///
- internal static int BitwiseAnd (int first, int second)
- {
- return first & second;
- }
-
- ///
- /// Perform a bitwise XOR on the first and second (first ^ second)
- ///
- internal static int BitwiseXor (int first, int second)
- {
- return first ^ second;
- }
-
- ///
- /// Perform a bitwise NOT on the first and second (~first)
- ///
- internal static int BitwiseNot (int first)
- {
- return ~first;
- }
-
- ///
- /// Get the value of the registry key and value, default value is null
- ///
- internal static object GetRegistryValue(string keyName, string valueName)
- {
- return Registry.GetValue(keyName, valueName, null /* null to match the $(Regsitry:XYZ@ZBC) behaviour */);
- }
-
- ///
- /// Get the value of the registry key and value
- ///
- internal static object GetRegistryValue(string keyName, string valueName, object defaultValue)
- {
- return Registry.GetValue(keyName, valueName, defaultValue);
- }
-
- ///
- /// Get the value of the registry key from one of the RegistryView's specified
- ///
- internal static object GetRegistryValueFromView(string keyName, string valueName, object defaultValue, params object[] views)
- {
- string subKeyName;
-
- // We will take on handing of default value
- // A we need to act on the null return from the GetValue call below
- // so we can keep searching other registry views
- object result = defaultValue;
-
- // If we haven't been passed any views, then we'll just use the default view
- if (views == null || views.Length == 0)
- {
- views = new object[] { RegistryView.Default };
- }
-
- foreach (object viewObject in views)
- {
- string viewAsString = viewObject as string;
-
- if (viewAsString != null)
- {
- string typeLeafName = typeof(RegistryView).Name + ".";
- string typeFullName = typeof(RegistryView).FullName + ".";
-
- // We'll allow the user to specify the leaf or full type name on the RegistryView enum
- viewAsString = viewAsString.Replace(typeFullName, "").Replace(typeLeafName, "");
-
- // This may throw - and that's fine as the user will receive a controlled version
- // of that error.
- RegistryView view = (RegistryView)Enum.Parse(typeof(RegistryView), viewAsString, true);
-
- if (!Platform.IsWindows && !keyName.StartsWith("HKEY_CURRENT_USER", StringComparison.OrdinalIgnoreCase))
- {
- // Fake common requests to HKLM that we can resolve
-
-
- // See if this asks for a specific SDK
- var m = Regex.Match(keyName,
- @"^HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Microsoft SDKs\\Windows\\v(\d+\.\d+)$",
- RegexOptions.IgnoreCase);
- if (m.Success && m.Groups.Count >= 1 && valueName.Equals("InstallRoot", StringComparison.OrdinalIgnoreCase))
- {
- var mr = MonoDevelop.Core.Runtime.SystemAssemblyService.DefaultRuntime as MonoTargetRuntime;
- if (mr != null)
- return Path.Combine (mr.MonoDirectory, m.Groups [0].Value) + Path.DirectorySeparatorChar;
- }
-
- return string.Empty;
- }
-
- using (RegistryKey key = GetBaseKeyFromKeyName(keyName, view, out subKeyName))
- {
- if (key != null)
- {
- using (RegistryKey subKey = key.OpenSubKey(subKeyName, false))
- {
- // If we managed to retrieve the subkey, then move onto locating the value
- if (subKey != null)
- {
- result = subKey.GetValue(valueName);
- }
-
- // We've found a value, so stop looking
- if (result != null)
- {
- break;
- }
- }
- }
- }
- }
- }
-
- // We will have either found a result or defaultValue if one wasn't found at this point
- return result;
- }
-
- ///
- /// Given the absolute location of a file, and a disc location, returns relative file path to that disk location.
- /// Throws UriFormatException.
- ///
- ///
- /// The base path we want to relativize to. Must be absolute.
- /// Should not include a filename as the last segment will be interpreted as a directory.
- ///
- ///
- /// The path we need to make relative to basePath. The path can be either absolute path or a relative path in which case it is relative to the base path.
- /// If the path cannot be made relative to the base path (for example, it is on another drive), it is returned verbatim.
- ///
- /// relative path (can be the full path)
- internal static string MakeRelative (string basePath, string path)
- {
- string result = FileService.AbsoluteToRelativePath (basePath, path);
-
- return result;
- }
-
- ///
- /// Locate a file in either the directory specified or a location in the
- /// direcorty structure above that directory.
- ///
- internal static string GetDirectoryNameOfFileAbove (string startingDirectory, string fileName)
- {
- // Canonicalize our starting location
- string lookInDirectory = Path.GetFullPath (startingDirectory);
-
- do {
- // Construct the path that we will use to test against
- string possibleFileDirectory = Path.Combine (lookInDirectory, fileName);
-
- // If we successfully locate the file in the directory that we're
- // looking in, simply return that location. Otherwise we'll
- // keep moving up the tree.
- if (File.Exists (possibleFileDirectory)) {
- // We've found the file, return the directory we found it in
- return lookInDirectory;
- } else {
- // GetDirectoryName will return null when we reach the root
- // terminating our search
- lookInDirectory = Path.GetDirectoryName (lookInDirectory);
- }
- }
- while (lookInDirectory != null);
-
- // When we didn't find the location, then return an empty string
- return String.Empty;
- }
-
- ///
- /// Searches for a file based on the specified .
- ///
- /// The file to search for.
- /// An optional directory to start the search in. The default location is the directory
- /// of the file containing the property funciton.
- /// The full path of the file if it is found, otherwise an empty string.
- internal static string GetPathOfFileAbove (string file, string startingDirectory)
- {
- // This method does not accept a path, only a file name
- if (file.Any (i => i.Equals (Path.DirectorySeparatorChar) || i.Equals (Path.AltDirectorySeparatorChar))) {
- throw new ArgumentException ("InvalidGetPathOfFileAboveParameter", file);
- }
-
- // Search for a directory that contains that file
- string directoryName = GetDirectoryNameOfFileAbove (startingDirectory, file);
-
- return String.IsNullOrWhiteSpace (directoryName) ? String.Empty : NormalizePath (directoryName, file);
- }
-
- ///
- /// Return the string in parameter 'defaultValue' only if parameter 'conditionValue' is empty
- /// else, return the value conditionValue
- ///
- internal static string ValueOrDefault (string conditionValue, string defaultValue)
- {
- if (String.IsNullOrEmpty (conditionValue)) {
- return defaultValue;
- } else {
- return conditionValue;
- }
- }
-
- ///
- /// Returns true if a task host exists that can service the requested runtime and architecture
- /// values, and false otherwise.
- ///
- internal static bool DoesTaskHostExist (string runtime, string architecture)
- {
- return false;
- }
-
- ///
- /// If the given path doesn't have a trailing slash then add one.
- /// If the path is an empty string, does not modify it.
- ///
- /// The path to check.
- /// The specified path with a trailing slash.
- internal static string EnsureTrailingSlash (string path)
- {
- return FileUtilities.EnsureTrailingSlash (path);
- }
-
- ///
- /// Gets the canonicalized full path of the provided directory and ensures it contains the correct directory separator characters for the current operating system
- /// while ensuring it has a trailing slash.
- ///
- /// One or more directory paths to combine and normalize.
- /// A canonicalized full directory path with the correct directory separators and a trailing slash.
- internal static string NormalizeDirectory (params string [] path)
- {
- return EnsureTrailingSlash (NormalizePath (path));
- }
-
- ///
- /// Gets the canonicalized full path of the provided path and ensures it contains the correct directory separator characters for the current operating system.
- ///
- /// One or more paths to combine and normalize.
- /// A canonicalized full path with the correct directory separators.
- internal static string NormalizePath (params string [] path)
- {
- return FileUtilities.NormalizePath (Path.Combine (path));
- }
-
- ///
- /// Specify whether the current OS platform is
- ///
- /// The platform string. Must be a member of . Case Insensitive
- ///
- internal static bool IsOSPlatform (string platformString)
- {
- return RuntimeInformation.IsOSPlatform (OSPlatform.Create (platformString.ToUpperInvariant ()));
- }
-
- ///
- /// True if current OS is a Unix system.
- ///
- ///
- internal static bool IsOsUnixLike ()
- {
- return !Platform.IsWindows;
- }
-
- //public static string GetCurrentToolsDirectory ()
- //{
- // return BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory;
- //}
-
- //public static string GetToolsDirectory32 ()
- //{
- // return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory32;
- //}
-
- //public static string GetToolsDirectory64 ()
- //{
- // return BuildEnvironmentHelper.Instance.MSBuildToolsDirectory64;
- //}
-
- //public static string GetMSBuildSDKsPath ()
- //{
- // return BuildEnvironmentHelper.Instance.MSBuildSDKsPath;
- //}
-
- //public static string GetVsInstallRoot ()
- //{
- // return BuildEnvironmentHelper.Instance.VisualStudioInstallRootDirectory;
- //}
-
- //public static string GetProgramFiles32 ()
- //{
- // return FrameworkLocationHelper.programFiles32;
- //}
-
- //public static string GetMSBuildExtensionsPath ()
- //{
- // return BuildEnvironmentHelper.Instance.MSBuildExtensionsPath;
- //}
-
- #region Debug only intrinsics
-
- ///
- /// returns if the string contains escaped wildcards
- ///
- internal static List __GetListTest ()
- {
- return new List { "A", "B", "C", "D" };
- }
-
- #endregion
-
- ///
- /// Following function will parse a keyName and returns the basekey for it.
- /// It will also store the subkey name in the out parameter.
- /// If the keyName is not valid, we will throw ArgumentException.
- /// The return value shouldn't be null.
- /// Taken from: \ndp\clr\src\BCL\Microsoft\Win32\Registry.cs
- ///
- private static RegistryKey GetBaseKeyFromKeyName(string keyName, RegistryView view, out string subKeyName)
- {
- if (keyName == null)
- {
- throw new ArgumentNullException("keyName");
- }
-
- string basekeyName;
- int i = keyName.IndexOf('\\');
- if (i != -1)
- {
- basekeyName = keyName.Substring(0, i).ToUpperInvariant();
- }
- else
- {
- basekeyName = keyName.ToUpperInvariant();
- }
-
- RegistryKey basekey = null;
-
- switch (basekeyName)
- {
- case "HKEY_CURRENT_USER":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, view);
- break;
- case "HKEY_LOCAL_MACHINE":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, view);
- break;
- case "HKEY_CLASSES_ROOT":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, view);
- break;
- case "HKEY_USERS":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.Users, view);
- break;
- case "HKEY_PERFORMANCE_DATA":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.PerformanceData, view);
- break;
- case "HKEY_CURRENT_CONFIG":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.CurrentConfig, view);
- break;
- case "HKEY_DYN_DATA":
- basekey = RegistryKey.OpenBaseKey(RegistryHive.DynData, view);
- break;
- default:
- throw new ArgumentException (keyName);
- }
-
- if (i == -1 || i == keyName.Length)
- {
- subKeyName = string.Empty;
- }
- else
- {
- subKeyName = keyName.Substring(i + 1, keyName.Length - i - 1);
- }
-
- return basekey;
- }
- }
-}
\ No newline at end of file
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs
index 34d9058f179..11190095108 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs
@@ -89,10 +89,10 @@ public MSBuildEvaluationContext (MSBuildEvaluationContext parentContext)
internal void InitEvaluation (MSBuildProject project)
{
- this.project = project;
-
- // Project file properties
-
+ this.project = project;
+
+ // Project file properties
+
properties.Add ("MSBuildThisFile", Path.GetFileName (project.FileName));
properties.Add ("MSBuildThisFileName", project.FileName.FileNameWithoutExtension);
properties.Add ("MSBuildThisFileExtension", Path.GetExtension (project.FileName));
@@ -100,10 +100,10 @@ internal void InitEvaluation (MSBuildProject project)
string dir = Path.GetDirectoryName (project.FileName) + Path.DirectorySeparatorChar;
properties.Add ("MSBuildThisFileDirectory", MSBuildProjectService.ToMSBuildPath (null, dir));
- properties.Add ("MSBuildThisFileDirectoryNoRoot", MSBuildProjectService.ToMSBuildPath (null, dir.Substring (Path.GetPathRoot (dir).Length)));
-
- // Properties only set for the root project, not for imported projects
-
+ properties.Add ("MSBuildThisFileDirectoryNoRoot", MSBuildProjectService.ToMSBuildPath (null, dir.Substring (Path.GetPathRoot (dir).Length)));
+
+ // Properties only set for the root project, not for imported projects
+
if (parentContext == null) {
properties.Add ("VisualStudioReferenceAssemblyVersion", project.ToolsVersion + ".0.0");
properties.Add ("MSBuildProjectDefaultTargets", project.DefaultTargets);
@@ -117,10 +117,14 @@ internal void InitEvaluation (MSBuildProject project)
properties.Add ("MSBuildProjectDirectoryNoRoot", MSBuildProjectService.ToMSBuildPath (null, dir.Substring (Path.GetPathRoot (dir).Length)));
InitEngineProperties (project.TargetRuntime ?? Runtime.SystemAssemblyService.DefaultRuntime, properties, out searchPaths);
- }
+ }
}
- static void InitEngineProperties (Core.Assemblies.TargetRuntime runtime, Dictionary properties, out List searchPaths)
+ // These are initialised in 'InitEngineProperties' below
+ static Type typeofIntrinsicFunctions; // = typeof ("Microsoft.Build.Evaluation.IntrinsicFunctions")
+ static Dictionary cachedIntrinsicFunctions;
+
+ static void InitEngineProperties (Core.Assemblies.TargetRuntime runtime, Dictionary properties, out List searchPaths)
{
string toolsVersion = "Current";
string visualStudioVersion = "16.0";
@@ -150,39 +154,50 @@ static void InitEngineProperties (Core.Assemblies.TargetRuntime runtime, Diction
var frameworkToolsPath = ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.VersionLatest);
var frameworkToolsPathEscaped = MSBuildProjectService.ToMSBuildPath (null, frameworkToolsPath);
properties.Add ("MSBuildFrameworkToolsPath", frameworkToolsPathEscaped);
- properties.Add ("MSBuildFrameworkToolsPath32", frameworkToolsPathEscaped);
-
+ properties.Add ("MSBuildFrameworkToolsPath32", frameworkToolsPathEscaped);
+
searchPaths = MSBuildProjectService.GetProjectImportSearchPaths (runtime, true).ToList ();
- if (Platform.IsWindows) {
- //first use extensions path relative to bindir (MSBuild/15.0/Bin). this works for dev15 isolated install.
- var msBuildExtensionsPath = Path.GetFullPath (Path.Combine (msBuildBinPath, "..", ".."));
- var msBuildExtensionsPathEscaped = MSBuildProjectService.ToMSBuildPath (null, msBuildExtensionsPath);
- properties.Add ("MSBuildExtensionsPath", msBuildExtensionsPathEscaped);
- properties.Add ("MSBuildExtensionsPath32", msBuildExtensionsPathEscaped);
- properties.Add ("MSBuildExtensionsPath64", msBuildExtensionsPathEscaped);
-
+ // initialise the static Dictionary 'cachedIntrinsicFunctions' from Microsoft.Build.dll IntrinsicFunctions
+ // this avoids re-importing all msBuild IntrinsicFunctions into MonoDevelop code whenever they change (ie often)
+
+ Assembly microsoftBuild = Assembly.LoadFrom (msBuildBinPath + "/Microsoft.Build.dll");
+ typeofIntrinsicFunctions = microsoftBuild.GetType ("Microsoft.Build.Evaluation.IntrinsicFunctions");
+
+ cachedIntrinsicFunctions = typeofIntrinsicFunctions
+ .GetMethods (BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Static)
+ .ToLookup (x => x.Name)
+ .ToDictionary (x => x.Key, x => x.ToArray (), StringComparer.OrdinalIgnoreCase);
+
+ if (Platform.IsWindows) {
+ //first use extensions path relative to bindir (MSBuild/15.0/Bin). this works for dev15 isolated install.
+ var msBuildExtensionsPath = Path.GetFullPath (Path.Combine (msBuildBinPath, "..", ".."));
+ var msBuildExtensionsPathEscaped = MSBuildProjectService.ToMSBuildPath (null, msBuildExtensionsPath);
+ properties.Add ("MSBuildExtensionsPath", msBuildExtensionsPathEscaped);
+ properties.Add ("MSBuildExtensionsPath32", msBuildExtensionsPathEscaped);
+ properties.Add ("MSBuildExtensionsPath64", msBuildExtensionsPathEscaped);
+
var vsToolsPathEscaped = MSBuildProjectService.ToMSBuildPath (null, Path.Combine (msBuildExtensionsPath, "Microsoft", "VisualStudio", "v" + visualStudioVersion));
- properties.Add ("VSToolsPath", vsToolsPathEscaped);
-
- //like the dev15 toolset, add fallbacks to the old global paths
-
- // Taken from MSBuild source:
+ properties.Add ("VSToolsPath", vsToolsPathEscaped);
+
+ //like the dev15 toolset, add fallbacks to the old global paths
+
+ // Taken from MSBuild source:
var programFiles = Environment.GetFolderPath (Environment.SpecialFolder.ProgramFiles);
var programFiles32 = Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86);
if (string.IsNullOrEmpty (programFiles32))
- programFiles32 = programFiles; // 32 bit box
-
+ programFiles32 = programFiles; // 32 bit box
+
string programFiles64;
- if (programFiles == programFiles32) {
- // either we're in a 32-bit window, or we're on a 32-bit machine.
- // if we're on a 32-bit machine, ProgramW6432 won't exist
- // if we're on a 64-bit machine, ProgramW6432 will point to the correct Program Files.
+ if (programFiles == programFiles32) {
+ // either we're in a 32-bit window, or we're on a 32-bit machine.
+ // if we're on a 32-bit machine, ProgramW6432 won't exist
+ // if we're on a 64-bit machine, ProgramW6432 will point to the correct Program Files.
programFiles64 = Environment.GetEnvironmentVariable ("ProgramW6432");
}
- else {
- // 64-bit window on a 64-bit machine; %ProgramFiles% points to the 64-bit
- // Program Files already.
+ else {
+ // 64-bit window on a 64-bit machine; %ProgramFiles% points to the 64-bit
+ // Program Files already.
programFiles64 = programFiles;
}
@@ -191,16 +206,16 @@ static void InitEngineProperties (Core.Assemblies.TargetRuntime runtime, Diction
if (programFiles64 != null) {
var extensionsPath64Escaped = MSBuildProjectService.ToMSBuildPath (null, Path.Combine (programFiles64, "MSBuild"));
- searchPaths.Insert (0, new ImportSearchPathExtensionNode { Property = "MSBuildExtensionsPath64", Path = extensionsPath64Escaped });
- }
-
- //yes, dev15's toolset has the 64-bit path fall back to the 32-bit one
- searchPaths.Insert (0, new ImportSearchPathExtensionNode { Property = "MSBuildExtensionsPath64", Path = extensionsPath32Escaped });
-
- // MSBuildExtensionsPath: The way this used to work is that it would point to "Program Files\MSBuild" on both
- // 32-bit and 64-bit machines. We have a switch to continue using that behavior; however the default is now for
- // MSBuildExtensionsPath to always point to the same location as MSBuildExtensionsPath32.
-
+ searchPaths.Insert (0, new ImportSearchPathExtensionNode { Property = "MSBuildExtensionsPath64", Path = extensionsPath64Escaped });
+ }
+
+ //yes, dev15's toolset has the 64-bit path fall back to the 32-bit one
+ searchPaths.Insert (0, new ImportSearchPathExtensionNode { Property = "MSBuildExtensionsPath64", Path = extensionsPath32Escaped });
+
+ // MSBuildExtensionsPath: The way this used to work is that it would point to "Program Files\MSBuild" on both
+ // 32-bit and 64-bit machines. We have a switch to continue using that behavior; however the default is now for
+ // MSBuildExtensionsPath to always point to the same location as MSBuildExtensionsPath32.
+
bool useLegacyMSBuildExtensionsPathBehavior = !string.IsNullOrEmpty (Environment.GetEnvironmentVariable ("MSBUILDLEGACYEXTENSIONSPATH"));
string extensionsPath;
@@ -215,23 +230,23 @@ static void InitEngineProperties (Core.Assemblies.TargetRuntime runtime, Diction
var msBuildExtensionsPathEscaped = MSBuildProjectService.ToMSBuildPath (null, msBuildExtensionsPath);
properties.Add ("MSBuildExtensionsPath", msBuildExtensionsPathEscaped);
properties.Add ("MSBuildExtensionsPath32", msBuildExtensionsPathEscaped);
- properties.Add ("MSBuildExtensionsPath64", msBuildExtensionsPathEscaped);
-
+ properties.Add ("MSBuildExtensionsPath64", msBuildExtensionsPathEscaped);
+
var vsToolsPathEscaped = MSBuildProjectService.ToMSBuildPath (null, Path.Combine (msBuildExtensionsPath, "Microsoft", "VisualStudio", "v" + visualStudioVersion));
properties.Add ("VSToolsPath", vsToolsPathEscaped);
- }
-
- // Environment
-
- properties.Add ("MSBuildProgramFiles32", MSBuildProjectService.ToMSBuildPath (null, Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86)));
-
- // Custom override of MSBuildExtensionsPath using an env var
-
+ }
+
+ // Environment
+
+ properties.Add ("MSBuildProgramFiles32", MSBuildProjectService.ToMSBuildPath (null, Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86)));
+
+ // Custom override of MSBuildExtensionsPath using an env var
+
var customExtensionsPath = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath");
if (!string.IsNullOrEmpty (customExtensionsPath)) {
- if (IsExternalMSBuildExtensionsPath (customExtensionsPath))
- // This is actually an override of the mono extensions path. Don't replace the default MSBuildExtensionsPath value since
- // core targets still need to be loaded from there.
+ if (IsExternalMSBuildExtensionsPath (customExtensionsPath))
+ // This is actually an override of the mono extensions path. Don't replace the default MSBuildExtensionsPath value since
+ // core targets still need to be loaded from there.
searchPaths.Insert (0, new ImportSearchPathExtensionNode { Property = "MSBuildExtensionsPath", Path = customExtensionsPath });
else
properties["MSBuildExtensionsPath"] = MSBuildProjectService.ToMSBuildPath (null, customExtensionsPath);
@@ -457,8 +472,10 @@ string Evaluate (string str, StringBuilder sb, List evalua
int j = i;
object val;
bool nie;
+
if (!EvaluateReference (str.AsSpan (), evaluatedItemsCollection, ref j, out val, out nie))
allResolved = false;
+
needsItemEvaluation |= nie;
sb.Append (ValueToString (val));
last = j;
@@ -557,6 +574,7 @@ bool EvaluateProperty (ReadOnlySpan prop, bool ignorePropsWithTransforms,
{
needsItemEvaluation = false;
val = null;
+
if (prop [0] == '[') {
int i = prop.IndexOf (']');
if (i == -1 || (prop.Length - i) < 3 || prop [i + 1] != ':' || prop [i + 2] != ':')
@@ -604,7 +622,6 @@ bool EvaluateMemberOrIndexer (Type type, object instance, ReadOnlySpan str
internal bool EvaluateMember (Type type, object instance, ReadOnlySpan str, int i, out object val)
{
val = null;
-
// Find the delimiter of the member
int j = str.IndexOfAny (MemberDelimiter, i);
if (j == -1)
@@ -618,6 +635,7 @@ internal bool EvaluateMember (Type type, object instance, ReadOnlySpan str
// It is a method invocation
object [] parameterValues;
j++;
+
if (!EvaluateParameters (str, ref j, out parameterValues))
return false;
@@ -690,6 +708,7 @@ internal bool EvaluateMember (ReadOnlySpan str, Type type, string memberNa
var member = ResolveMember (type, memberName, instance == null, MemberTypes.Method);
if (member == null || member.Length == 0)
return false;
+
return EvaluateMethod (str, member, instance, parameterValues, out val);
}
@@ -704,13 +723,13 @@ bool EvaluateMethod (ReadOnlySpan str, MemberInfo[] member, object instanc
try {
// Convert the given parameters to the types specified in the method signature
- var convertedArgs = (methodParams.Length == parameterValues.Length) ? parameterValues : new object [methodParams.Length];
+ var convertedArgs = (methodParams.Length == parameterValues.Length) ? parameterValues : new object [methodParams.Length];
int numArgs = methodParams.Length;
if (paramsArgType != null)
numArgs--;
- if (method.DeclaringType == typeof (IntrinsicFunctions) && method.Name == nameof (IntrinsicFunctions.GetPathOfFileAbove) && parameterValues.Length == methodParams.Length - 1) {
+ if (method.DeclaringType == typeofIntrinsicFunctions && method.Name == "GetPathOfFileAbove" && parameterValues.Length == methodParams.Length - 1) {
string startingDirectory = String.IsNullOrWhiteSpace (FullFileName) ? String.Empty : Path.GetDirectoryName (FullFileName);
var last = convertedArgs.Length - 1;
convertedArgs [last] = ConvertArg (method, last, startingDirectory, methodParams [last].ParameterType);
@@ -758,6 +777,7 @@ bool EvaluateMethod (ReadOnlySpan str, MemberInfo[] member, object instanc
}
}
val = method.Invoke (instance, convertedArgs);
+
} catch (Exception ex) {
LoggingService.LogError ("MSBuild property evaluation failed: " + str.ToString (), ex);
return false;
@@ -817,7 +837,7 @@ internal bool EvaluateParameters (ReadOnlySpan str, ref int i, out object[
var argInfo = m.GetParameters ();
if (args.Length == argInfo.Length - 1) {
- if (m.DeclaringType == typeof (IntrinsicFunctions) && m.Name == nameof (IntrinsicFunctions.GetPathOfFileAbove)) {
+ if (m.DeclaringType == typeofIntrinsicFunctions && m.Name == "GetPathOfFileAbove") {
validMatch = (m, argInfo);
continue;
}
@@ -986,7 +1006,7 @@ object ConvertArg (MethodBase method, int argNum, object value, Type parameterTy
else if (method.DeclaringType == typeof (System.IO.Path))
// The windows path is already converted to a native path, but it may contain escape sequences
res = MSBuildProjectService.UnescapePath ((string)res);
- else if (method.DeclaringType == typeof (IntrinsicFunctions)) {
+ else if (method.DeclaringType == typeofIntrinsicFunctions) {
if (method.Name == "MakeRelative")
convertPath = true;
else if (method.Name == "GetDirectoryNameOfFileAbove" && argNum == 0)
@@ -1017,7 +1037,7 @@ bool EvaluateList (ReadOnlySpan prop, List evaluated
Type ResolveType (string typeName)
{
if (typeName == "MSBuild")
- return typeof (Microsoft.Build.Evaluation.IntrinsicFunctions);
+ return typeofIntrinsicFunctions;
foreach (var kvp in supportedTypeMembers) {
if (kvp.Key.FullName == typeName)
@@ -1026,24 +1046,15 @@ Type ResolveType (string typeName)
return null;
}
- static readonly Dictionary cachedIntrinsicFunctions = typeof (IntrinsicFunctions)
- .GetMethods (BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Static)
- .ToLookup (x => x.Name)
- .ToDictionary(x => x.Key, x => x.ToArray (), StringComparer.OrdinalIgnoreCase);
-
- MemberInfo[] ResolveMember (Type type, string memberName, bool isStatic, MemberTypes memberTypes)
+ MemberInfo [] ResolveMember (Type type, string memberName, bool isStatic, MemberTypes memberTypes)
{
- if (type == typeof (string)) {
- if (memberName == "new" || memberName == "Copy") {
- type = typeof (IntrinsicFunctions);
- memberName = "Copy";
- }
- } else {
- if (type.IsArray)
- type = typeof (Array);
- }
+ if (type == typeof (string) && memberName == "new")
+ memberName = "Copy";
+
+ if (type.IsArray)
+ type = typeof (Array);
- if (type == typeof(IntrinsicFunctions)) {
+ if (type == typeofIntrinsicFunctions) {
return cachedIntrinsicFunctions.TryGetValue (memberName, out var result) ? result : null;
}
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/RoslynClassificationHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/RoslynClassificationHighlighting.cs
index 2825732724a..1fe62dfd719 100644
--- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/RoslynClassificationHighlighting.cs
+++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/RoslynClassificationHighlighting.cs
@@ -163,7 +163,7 @@ public async Task GetHighlightedLineAsync (IDocumentLine line,
if ( curSpan.TextSpan.Start == prevStart && curSpan.TextSpan.Length == prevLength )
{
- Console.WriteLine( "RCH.GetHighlightedLineAsync : SKIP overlapping SPAN start=" + curSpan.TextSpan.Start + " length=" + curSpan.TextSpan.Length + " ClassificationType='" + curSpan.ClassificationType + "'" );
+// Console.WriteLine( "RCH.GetHighlightedLineAsync : SKIP overlapping SPAN start=" + curSpan.TextSpan.Start + " length=" + curSpan.TextSpan.Length + " ClassificationType='" + curSpan.ClassificationType + "'" );
// Console.WriteLine( "RCH.GetHighlightedLineAsync : SKIP overlapping SPAN start=" + curSpan.TextSpan.Start + " length=" + curSpan.TextSpan.Length + " ClassificationType='" + curSpan.ClassificationType + "' lastClassifiedOffsetEnd=" + lastClassifiedOffsetEnd );
}
else
diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj
index 3f8c4a96cbb..ca66997c358 100644
--- a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj
+++ b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Core.Tests.csproj
@@ -126,9 +126,9 @@
-
+
{7525BB88-6142-4A26-93B9-A30C6983390A}
diff --git a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/IntrinsicFunctionsTests.cs b/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/IntrinsicFunctionsTests.cs
deleted file mode 100644
index d2fb49edfec..00000000000
--- a/main/tests/MonoDevelop.Core.Tests/MonoDevelop.Projects/IntrinsicFunctionsTests.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// IntrinsicFunctionsTests.cs
-//
-// Author:
-// Marius Ungureanu
-//
-// Copyright (c) 2019 Microsoft Inc.
-//
-// 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.Reflection;
-using System.Runtime.CompilerServices;
-using Microsoft.Build.Evaluation;
-using NUnit.Framework;
-
-namespace MonoDevelop.Projects
-{
- [TestFixture]
- public class IntrinsicFunctionsTests
- {
- [Test]
- public void TypeContainsOnlyMethods()
- {
- // MSBuildEvaluationContext.cachedIntrinsicFunctions only caches methods and code path only takes that into account
- foreach (var member in typeof(IntrinsicFunctions).GetMembers(BindingFlags.NonPublic | BindingFlags.Static)) {
- // Skip compiler generated code, such as lambda classes
- if (member.IsDefined (typeof (CompilerGeneratedAttribute)))
- continue;
-
- Assert.AreEqual (MemberTypes.Method, member.MemberType);
- }
- }
- }
-}