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:
Diffstat (limited to 'main/src/core/MonoDevelop.Core')
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkMoniker.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Core/FilePath.cs31
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ProjectTypeNode.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs293
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildFileFormat.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs32
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/ProjectEvaluationException.cs8
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs40
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs8
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MSBuildSerializationExtension.cs28
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs70
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectReader.cs12
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs6
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs2
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectReader.cs4
-rw-r--r--main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceSerializationExtension.cs10
21 files changed, 353 insertions, 225 deletions
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkMoniker.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkMoniker.cs
index 7b49c3be82..e6d4a4b32d 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkMoniker.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core.Assemblies/TargetFrameworkMoniker.cs
@@ -333,6 +333,10 @@ namespace MonoDevelop.Core.Assemblies
get { return new TargetFrameworkMoniker ("4.7.1"); }
}
+ public static TargetFrameworkMoniker NET_4_7_2 {
+ get { return new TargetFrameworkMoniker ("4.7.2"); }
+ }
+
public static TargetFrameworkMoniker PORTABLE_4_0 {
get { return new TargetFrameworkMoniker (ID_PORTABLE, "4.0", "Profile1"); }
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/FilePath.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/FilePath.cs
index c0e4238cb8..d48d076f05 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Core/FilePath.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Core/FilePath.cs
@@ -143,6 +143,14 @@ namespace MonoDevelop.Core
}
}
+ [Pure]
+ internal bool HasFileName (string name)
+ {
+ return fileName.Length > name.Length
+ && fileName.EndsWith (name, PathComparison)
+ && fileName [fileName.Length - name.Length - 1] == Path.DirectorySeparatorChar;
+ }
+
public string Extension {
get {
return Path.GetExtension (fileName);
@@ -153,8 +161,27 @@ namespace MonoDevelop.Core
public bool HasExtension (string extension)
{
return fileName.Length > extension.Length
- && fileName.EndsWith (extension, PathComparison)
- && fileName[fileName.Length - extension.Length - 1] != Path.PathSeparator;
+ && (extension == string.Empty
+ ? HasNoExtension (fileName)
+ : fileName.EndsWith (extension, PathComparison) && fileName [fileName.Length - extension.Length] == '.');
+
+ static bool HasNoExtension (string path)
+ {
+ // Look for the last dot that's after the last path separator
+ for (int i = path.Length - 1; i >= 0; --i) {
+ var ch = path [i];
+ if (ch == '.') {
+ // Check if it's the dot is the last character
+ // if it is, then we have no extension
+ return i == path.Length - 1;
+ }
+
+ if (ch == Path.DirectorySeparatorChar)
+ return true;
+ }
+
+ return true;
+ }
}
public string FileNameWithoutExtension {
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ProjectTypeNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ProjectTypeNode.cs
index 18d9d0e167..13d5beeaae 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ProjectTypeNode.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/ProjectTypeNode.cs
@@ -45,7 +45,7 @@ namespace MonoDevelop.Projects.Extensions
Project project = null;
if (!string.IsNullOrEmpty (fileName)) {
- p = await MSBuildProject.LoadAsync (fileName);
+ p = await MSBuildProject.LoadAsync (fileName).ConfigureAwait (false);
if (ctx != null && ctx.Solution != null) {
p.EngineManager = ctx.Solution.MSBuildEngineManager;
p.SolutionDirectory = ctx.Solution.ItemDirectory;
@@ -53,7 +53,7 @@ namespace MonoDevelop.Projects.Extensions
var migrators = MSBuildProjectService.GetMigrableFlavors (p.ProjectTypeGuids);
if (migrators.Count > 0)
- await MSBuildProjectService.MigrateFlavors (monitor, fileName, Guid, p, migrators);
+ await MSBuildProjectService.MigrateFlavors (monitor, fileName, Guid, p, migrators).ConfigureAwait (false);
var unsupporedFlavor = p.ProjectTypeGuids.FirstOrDefault (fid => !MSBuildProjectService.IsKnownFlavorGuid (fid) && !MSBuildProjectService.IsKnownTypeGuid (fid));
if (unsupporedFlavor != null) {
@@ -72,7 +72,7 @@ namespace MonoDevelop.Projects.Extensions
}
if (project == null)
- project = await base.CreateSolutionItem (monitor, ctx, fileName) as Project;
+ project = await base.CreateSolutionItem (monitor, ctx, fileName).ConfigureAwait(false) as Project;
if (project == null)
throw new InvalidOperationException ("Project node type is not a subclass of MonoDevelop.Projects.Project");
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs
index 46fa87c880..3cd16adde0 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.Extensions/SolutionItemTypeNode.cs
@@ -99,7 +99,7 @@ namespace MonoDevelop.Projects.Extensions
if (typeof(SolutionItemFactory).IsAssignableFrom (ItemType)) {
if (factory == null)
factory = (SolutionItemFactory)Activator.CreateInstance (ItemType);
- item = await factory.CreateItem (fileName, Guid);
+ item = await factory.CreateItem (fileName, Guid).ConfigureAwait (false);
} else
item = MSBuildProjectService.CreateUninitializedInstance (ItemType);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
index e821b48bf6..a22fc426c5 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/DefaultMSBuildEngine.cs
@@ -850,7 +850,7 @@ namespace MonoDevelop.Projects.MSBuild
static bool IsWildcardInclude (string include)
{
- return include.IndexOf ('*') != -1;
+ return include.IndexOfAny (wildcards) != -1;
}
IEnumerable<MSBuildItemEvaluated> ExpandWildcardFilePath (ProjectInfo pinfo, MSBuildEvaluationContext context, MSBuildItem sourceItem, string path, Regex directoryExcludeRegex)
@@ -1018,7 +1018,7 @@ namespace MonoDevelop.Projects.MSBuild
return it;
}
- static char[] wildcards = { '*', '%' };
+ static char[] wildcards = { '*', '?' };
void Evaluate (ProjectInfo project, MSBuildEvaluationContext context, MSBuildProperty prop)
{
@@ -1174,7 +1174,7 @@ namespace MonoDevelop.Projects.MSBuild
var fileName = Path.GetFileName (path);
- if (fileName.IndexOfAny (new [] { '*', '?' }) == -1) {
+ if (fileName.IndexOfAny (wildcards) == -1) {
// Not a wildcard. Keep searching if the file doesn't exist.
var result = File.Exists (path) ? new [] { path } : null;
keepSearching = result == null;
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 94ea9abfa3..e7626bece3 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs
@@ -614,10 +614,6 @@ namespace MonoDevelop.Projects.MSBuild
if (memberName.Length == 0)
return false;
- var member = ResolveMember (type, memberName.ToString (), instance == null);
- if (member == null || member.Length == 0)
- return false;
-
if (j < str.Length && str[j] == '(') {
// It is a method invocation
object [] parameterValues;
@@ -625,6 +621,10 @@ namespace MonoDevelop.Projects.MSBuild
if (!EvaluateParameters (str, ref j, out parameterValues))
return false;
+ var member = ResolveMember (type, memberName.ToString (), instance == null, MemberTypes.Method);
+ if (member == null || member.Length == 0)
+ return false;
+
if (!EvaluateMethod (str, member, instance, parameterValues, out val))
return false;
@@ -634,6 +634,10 @@ namespace MonoDevelop.Projects.MSBuild
} else {
// It has to be a property or field
try {
+ var member = ResolveMember (type, memberName.ToString (), instance == null, MemberTypes.Property | MemberTypes.Field);
+ if (member == null || member.Length == 0)
+ return false;
+
if (member[0] is PropertyInfo)
val = ((PropertyInfo)member[0]).GetValue (instance);
else if (member[0] is FieldInfo)
@@ -683,7 +687,7 @@ namespace MonoDevelop.Projects.MSBuild
internal bool EvaluateMember (ReadOnlySpan<char> str, Type type, string memberName, object instance, object [] parameterValues, out object val)
{
val = null;
- var member = ResolveMember (type, memberName, instance == null);
+ 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);
@@ -694,22 +698,17 @@ namespace MonoDevelop.Projects.MSBuild
val = null;
// Find a method with a matching number of parameters
- var method = FindBestOverload (member.OfType<MethodBase> (), parameterValues);
+ var (method, methodParams) = FindBestOverload (member, parameterValues, out var paramsArgType);
if (method == null)
return false;
try {
// Convert the given parameters to the types specified in the method signature
- var methodParams = method.GetParameters ();
-
var convertedArgs = (methodParams.Length == parameterValues.Length) ? parameterValues : new object [methodParams.Length];
int numArgs = methodParams.Length;
- Type paramsArgType = null;
- if (methodParams.Length > 0 && methodParams [methodParams.Length - 1].ParameterType.IsArray && methodParams [methodParams.Length - 1].IsDefined (typeof (ParamArrayAttribute))) {
- paramsArgType = methodParams [methodParams.Length - 1].ParameterType.GetElementType ();
+ if (paramsArgType != null)
numArgs--;
- }
if (method.DeclaringType == typeof (IntrinsicFunctions) && method.Name == nameof (IntrinsicFunctions.GetPathOfFileAbove) && parameterValues.Length == methodParams.Length - 1) {
string startingDirectory = String.IsNullOrWhiteSpace (FullFileName) ? String.Empty : Path.GetDirectoryName (FullFileName);
@@ -792,58 +791,158 @@ namespace MonoDevelop.Projects.MSBuild
return false;
}
- MethodBase FindBestOverload (IEnumerable<MethodBase> methods, object [] args)
+ (MethodBase method, ParameterInfo[] parameters) FindBestOverload (IEnumerable<MemberInfo> members, object [] args, out Type paramsArgType)
{
- MethodBase methodWithParams = null;
+ (MethodBase, ParameterInfo[]) methodWithParams = default;
+ (MethodBase, ParameterInfo[]) validMatch = default;
- foreach (var m in methods) {
- var argInfo = m.GetParameters ();
+ paramsArgType = null;
- // Exclude methods which take a complex object as argument
- if (argInfo.Any (a => a.ParameterType != typeof(object) && Type.GetTypeCode (a.ParameterType) == TypeCode.Object && !IsParamsArg(a)))
+ foreach (var member in members) {
+ if (!(member is MethodBase m))
continue;
- if (args.Length >= argInfo.Length - 1 && argInfo.Length > 0 && IsParamsArg (argInfo [argInfo.Length - 1])) {
- methodWithParams = m;
- continue;
- }
- if (args.Length != argInfo.Length) {
- if (args.Length == argInfo.Length - 1 && m.DeclaringType != typeof (IntrinsicFunctions) || m.Name != nameof(IntrinsicFunctions.GetPathOfFileAbove)) {
+ var argInfo = m.GetParameters ();
+
+ if (args.Length == argInfo.Length - 1) {
+ if (m.DeclaringType == typeof (IntrinsicFunctions) && m.Name == nameof (IntrinsicFunctions.GetPathOfFileAbove)) {
+ validMatch = (m, argInfo);
continue;
}
}
- bool isValid = true;
- for (int n = 0; n < args.Length; n++) {
- if (!CanConvertArg (m, n, args [n], argInfo [n].ParameterType)) {
- isValid = false;
- break;
- }
+ // Unable to match in this case.
+ if (args.Length < argInfo.Length - 1)
+ continue;
+
+ var kind = MatchArgs (args, argInfo);
+ if (kind == MatchKind.Exact)
+ return (m, argInfo);
+
+ if (kind == MatchKind.CanConvert)
+ validMatch = (m, argInfo);
+ else if (kind == MatchKind.Params) {
+ methodWithParams = (m, argInfo);
+ paramsArgType = argInfo [argInfo.Length - 1].ParameterType.GetElementType ();
}
- if (isValid)
- return m;
}
- return methodWithParams;
+
+ return validMatch != default ? validMatch : methodWithParams;
}
- bool IsParamsArg (ParameterInfo pi)
+ enum MatchKind
+ {
+ None,
+ Params,
+ CanConvert,
+ Exact,
+ }
+
+ static MatchKind MatchArgs (object[] args, ParameterInfo[] parameters)
+ {
+ bool isParams = parameters.Length > 0 && IsParamsArg (parameters [parameters.Length - 1]);
+
+ int last = parameters.Length;
+ if (isParams)
+ last--;
+ else if (args.Length != parameters.Length)
+ return MatchKind.None;
+
+ var kind = MatchKind.Exact;
+ for (int n = 0; n < last; n++) {
+ var parameterType = parameters [n].ParameterType;
+
+ var other = Match (parameterType, args [n]);
+ if (other == MatchKind.None)
+ return MatchKind.None;
+
+ if (other == MatchKind.CanConvert)
+ kind = MatchKind.CanConvert;
+ }
+
+ if (!isParams)
+ return kind;
+
+ // Check implicit argument
+ if (args.Length == last)
+ return MatchKind.Params;
+
+ var elementType = parameters[last].ParameterType.GetElementType ();
+ if (IsComplexType (elementType))
+ return MatchKind.None;
+
+ int argsRemaining = args.Length - last;
+ if (argsRemaining == 1 && elementType == typeof(char)) {
+ if (Match (parameters [last].ParameterType, args [last], checkComplexType: false) != MatchKind.None)
+ return MatchKind.Params;
+ }
+
+ for (int n_arg = last; n_arg < args.Length; ++n_arg) {
+ if (Match (elementType, args [n_arg]) == MatchKind.None)
+ return MatchKind.None;
+ }
+
+ return MatchKind.Params;
+
+ static bool IsComplexType (Type type)
+ {
+ return Type.GetTypeCode (type) == TypeCode.Object && type != typeof (object);
+ }
+
+ static MatchKind Match (Type parameterType, object argument, bool checkComplexType = true)
+ {
+ if (parameterType.IsInstanceOfType (argument))
+ return MatchKind.Exact;
+
+ if (checkComplexType && IsComplexType (parameterType))
+ return MatchKind.None;
+
+ if (CanConvertArg (argument, parameterType))
+ return MatchKind.CanConvert;
+
+
+ return MatchKind.None;
+ }
+ }
+
+ static bool IsParamsArg (ParameterInfo pi)
{
return pi.ParameterType.IsArray && pi.IsDefined (typeof (ParamArrayAttribute));
}
- bool CanConvertArg (MethodBase method, int argNum, object value, Type parameterType)
+ static bool CanConvertArg (object value, Type parameterType)
{
var sval = value as string;
if (sval == "null" || value == null)
- return !parameterType.IsValueType || typeof(Nullable).IsInstanceOfType (parameterType);
+ return !parameterType.IsValueType || Nullable.GetUnderlyingType (parameterType) != null;
if (sval != null && parameterType == typeof (char []))
return true;
- if (parameterType == typeof (char) && sval != null && sval.Length != 1)
+ if (sval != null && sval.Length != 1 && parameterType == typeof (char)) {
return false;
+ }
- return true;
+ if (sval != null && parameterType.IsEnum) {
+ // Enum.Parse expects comma separated values.
+ var enumValue = sval.Replace ('|', ',')
+ .Replace (parameterType.FullName + ".", "")
+ .Replace (parameterType.Name + ".", "");
+
+ try {
+ _ = Enum.Parse (parameterType, enumValue, ignoreCase: true);
+ return true;
+ } catch {
+ return false;
+ }
+ }
+
+ try {
+ _ = Convert.ChangeType (value, parameterType, CultureInfo.InvariantCulture);
+ return true;
+ } catch {
+ return false;
+ }
}
object ConvertArg (MethodBase method, int argNum, object value, Type parameterType)
@@ -856,11 +955,11 @@ namespace MonoDevelop.Projects.MSBuild
return sval.ToCharArray ();
if (sval != null && parameterType.IsEnum) {
- var enumValue = sval;
- if (enumValue.StartsWith (parameterType.Name, StringComparison.Ordinal))
- enumValue = enumValue.Substring (parameterType.Name.Length + 1);
- if (enumValue.StartsWith (parameterType.FullName, StringComparison.Ordinal))
- enumValue = enumValue.Substring (parameterType.FullName.Length + 1);
+ // Enum.Parse expects comma separated values.
+ var enumValue = sval.Replace ('|', ',')
+ .Replace (parameterType.FullName + ".", "")
+ .Replace (parameterType.Name + ".", "");
+
return Enum.Parse(parameterType, enumValue, ignoreCase: true);
}
@@ -907,15 +1006,15 @@ namespace MonoDevelop.Projects.MSBuild
{
if (typeName == "MSBuild")
return typeof (Microsoft.Build.Evaluation.IntrinsicFunctions);
- else {
- var t = supportedTypeMembers.FirstOrDefault (st => st.Item1.FullName == typeName);
- if (t == null)
- return null;
- return t.Item1;
+
+ foreach (var kvp in supportedTypeMembers) {
+ if (kvp.Key.FullName == typeName)
+ return kvp.Key;
}
+ return null;
}
- MemberInfo[] ResolveMember (Type type, string memberName, bool isStatic)
+ MemberInfo[] ResolveMember (Type type, string memberName, bool isStatic, MemberTypes memberTypes)
{
if (type == typeof (string) && memberName == "new")
memberName = "Copy";
@@ -923,52 +1022,68 @@ namespace MonoDevelop.Projects.MSBuild
type = typeof (Array);
var flags = isStatic ? BindingFlags.Static : BindingFlags.Instance;
if (type != typeof (Microsoft.Build.Evaluation.IntrinsicFunctions)) {
- var t = supportedTypeMembers.FirstOrDefault (st => st.Item1 == type);
- if (t == null)
+ if (!supportedTypeMembers.TryGetValue (type, out var list))
return null;
- if (t.Item2 != null && !t.Item2.Contains (memberName))
+
+ if (list != null && !list.Contains (memberName))
return null;
} else
flags |= BindingFlags.NonPublic;
-
- return type.GetMember (memberName, flags | BindingFlags.Public | BindingFlags.IgnoreCase);
+
+ return type.GetMember (memberName, memberTypes, flags | BindingFlags.Public | BindingFlags.IgnoreCase);
}
- static Tuple<Type, string []> [] supportedTypeMembers = {
- Tuple.Create (typeof(System.Array), (string[]) null),
- Tuple.Create (typeof(System.Byte), (string[]) null),
- Tuple.Create (typeof(System.Char), (string[]) null),
- Tuple.Create (typeof(System.Convert), (string[]) null),
- Tuple.Create (typeof(System.DateTime), (string[]) null),
- Tuple.Create (typeof(System.Decimal), (string[]) null),
- Tuple.Create (typeof(System.Double), (string[]) null),
- Tuple.Create (typeof(System.Enum), (string[]) null),
- Tuple.Create (typeof(System.Guid), (string[]) null),
- Tuple.Create (typeof(System.Int16), (string[]) null),
- Tuple.Create (typeof(System.Int32), (string[]) null),
- Tuple.Create (typeof(System.Int64), (string[]) null),
- Tuple.Create (typeof(System.IO.Path), (string[]) null),
- Tuple.Create (typeof(System.Math), (string[]) null),
- Tuple.Create (typeof(System.UInt16), (string[]) null),
- Tuple.Create (typeof(System.UInt32), (string[]) null),
- Tuple.Create (typeof(System.UInt64), (string[]) null),
- Tuple.Create (typeof(System.SByte), (string[]) null),
- Tuple.Create (typeof(System.Single), (string[]) null),
- Tuple.Create (typeof(System.String), (string[]) null),
- Tuple.Create (typeof(System.StringComparer), (string[]) null),
- Tuple.Create (typeof(System.TimeSpan), (string[]) null),
- Tuple.Create (typeof(System.Text.RegularExpressions.Regex), (string[]) null),
- Tuple.Create (typeof(Microsoft.Build.Utilities.ToolLocationHelper), (string[]) null),
- Tuple.Create (typeof(System.Globalization.CultureInfo), (string[]) null),
- Tuple.Create (typeof(System.Environment), new string [] {
- "CommandLine", "ExpandEnvironmentVariables", "GetEnvironmentVariable", "GetEnvironmentVariables", "GetFolderPath", "GetLogicalDrives"
- }),
- Tuple.Create (typeof(System.IO.Directory), new string [] {
- "GetDirectories", "GetFiles", "GetLastAccessTime", "GetLastWriteTime", "GetParent"
- }),
- Tuple.Create (typeof(System.IO.File), new string [] {
- "Exists", "GetCreationTime", "GetAttributes", "GetLastAccessTime", "GetLastWriteTime", "ReadAllText"
- }),
+ sealed class TypeEqualityComparer : IEqualityComparer<Type>
+ {
+ public bool Equals (Type x, Type y) => x == y;
+
+ public int GetHashCode (Type obj) => obj?.GetHashCode () ?? 0;
+ }
+
+ static readonly Dictionary<Type, string []> supportedTypeMembers = new Dictionary<Type, string []> (new TypeEqualityComparer()) {
+ { typeof(System.Array), null },
+ { typeof(System.Byte), null },
+ { typeof(System.Char), null },
+ { typeof(System.Convert), null },
+ { typeof(System.DateTime), null },
+ { typeof(System.Decimal), null },
+ { typeof(System.Double), null },
+ { typeof(System.Enum), null },
+ { typeof(System.Guid), null },
+ { typeof(System.Int16), null },
+ { typeof(System.Int32), null },
+ { typeof(System.Int64), null },
+ { typeof(System.IO.Path), null },
+ { typeof(System.Math), null },
+ { typeof(System.UInt16), null },
+ { typeof(System.UInt32), null },
+ { typeof(System.UInt64), null },
+ { typeof(System.SByte), null },
+ { typeof(System.Single), null },
+ { typeof(System.String), null },
+ { typeof(System.StringComparer), null },
+ { typeof(System.TimeSpan), null },
+ { typeof(System.Text.RegularExpressions.Regex), null },
+ { typeof(Microsoft.Build.Utilities.ToolLocationHelper), null },
+ { typeof(System.Globalization.CultureInfo), null },
+ {
+ typeof (System.Environment),
+ new string [] {
+ "CommandLine", "ExpandEnvironmentVariables", "GetEnvironmentVariable", "GetEnvironmentVariables", "GetFolderPath", "GetLogicalDrives"
+ }
+ },
+ {
+ typeof (System.IO.Directory),
+ new string [] {
+ "GetDirectories", "GetFiles", "GetLastAccessTime", "GetLastWriteTime", "GetParent"
+ }
+ },
+ {
+ typeof (System.IO.File),
+ new string [] {
+ "Exists", "GetCreationTime", "GetAttributes", "GetLastAccessTime", "GetLastWriteTime", "ReadAllText"
+ }
+ },
};
int FindNextTag (string str, int i)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildFileFormat.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildFileFormat.cs
index e7c8945f90..fe0e089335 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildFileFormat.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildFileFormat.cs
@@ -168,7 +168,7 @@ namespace MonoDevelop.Projects.MSBuild
internal async Task WriteFile (FilePath file, object obj, ProgressMonitor monitor)
{
if (slnFileFormat.CanWriteFile (obj, this)) {
- await slnFileFormat.WriteFile (file, obj, true, monitor);
+ await slnFileFormat.WriteFile (file, obj, true, monitor).ConfigureAwait (false);
} else {
throw new NotSupportedException ();
}
@@ -177,7 +177,7 @@ namespace MonoDevelop.Projects.MSBuild
internal async Task<object> ReadFile (FilePath file, Type expectedType, MonoDevelop.Core.ProgressMonitor monitor)
{
if (slnFileFormat.CanReadFile (file, this))
- return await slnFileFormat.ReadFile (file, monitor);
+ return await slnFileFormat.ReadFile (file, monitor).ConfigureAwait(false);
else
throw new NotSupportedException ();
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs
index a23254c86c..4b21073b76 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectInstance.cs
@@ -115,7 +115,7 @@ namespace MonoDevelop.Projects.MSBuild
} catch (Exception ex) {
// If the project can't be evaluated don't crash
LoggingService.LogError ("MSBuild project could not be evaluated", ex);
- throw new ProjectEvaluationException (msproject, ex.Message);
+ throw new ProjectEvaluationException (msproject, ex.Message, ex);
} finally {
if (oldProjectInstance != null)
engine.DisposeProjectInstance (oldProjectInstance);
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs
index 703bbcf97d..398aa31187 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs
@@ -784,26 +784,24 @@ namespace MonoDevelop.Projects.MSBuild
return Task.FromResult<SolutionItem> (new GenericProject ());
// Unknown project types are already displayed in the solution view, we don't need to tell the user with a modal dialog as well
- return Task<SolutionItem>.Factory.StartNew (delegate {
- var t = ReadGenericProjectType (file);
- if (t == null)
- throw new UnknownSolutionItemTypeException (GettextCatalog.GetString ("Unknown project type"));
+ var t = ReadGenericProjectType (file);
+ if (t == null)
+ return Task.FromException<SolutionItem> (new UnknownSolutionItemTypeException (GettextCatalog.GetString ("Unknown project type")));
- var dt = Services.ProjectService.DataContext.GetConfigurationDataType (t);
- if (dt != null) {
- if (!typeof (Project).IsAssignableFrom (dt.ValueType))
- throw new UnknownSolutionItemTypeException (GettextCatalog.GetString ("Unknown project type: {0}", t));
+ var dt = Services.ProjectService.DataContext.GetConfigurationDataType (t);
+ if (dt != null) {
+ if (!typeof (Project).IsAssignableFrom (dt.ValueType))
+ return Task.FromException<SolutionItem> (new UnknownSolutionItemTypeException (GettextCatalog.GetString ("Unknown project type: {0}", t)));
- return (SolutionItem)Activator.CreateInstance (dt.ValueType);
- }
+ return Task.FromResult ((SolutionItem)Activator.CreateInstance (dt.ValueType));
+ }
- Type type;
- lock (genericProjectTypes) {
- if (!genericProjectTypes.TryGetValue (t, out type))
- throw new UnknownSolutionItemTypeException (GettextCatalog.GetString ("Unknown project type: {0}", t));
- }
- return (SolutionItem)Activator.CreateInstance (type);
- });
+ Type type;
+ lock (genericProjectTypes) {
+ if (!genericProjectTypes.TryGetValue (t, out type))
+ return Task.FromException<SolutionItem> (new UnknownSolutionItemTypeException (GettextCatalog.GetString ("Unknown project type: {0}", t)));
+ }
+ return Task.FromResult ((SolutionItem)Activator.CreateInstance (type));
}
static string ReadGenericProjectType (string file)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/ProjectEvaluationException.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/ProjectEvaluationException.cs
index 000fcea525..88775b3e5d 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/ProjectEvaluationException.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/ProjectEvaluationException.cs
@@ -29,12 +29,16 @@ namespace MonoDevelop.Projects.MSBuild
{
public class ProjectEvaluationException: ApplicationException
{
- public ProjectEvaluationException (MSBuildProject project, string message): base (message)
+ internal ProjectEvaluationException (MSBuildProject project, string message, Exception innerException) : base (message, innerException)
{
Project = project;
}
- public MSBuildProject Project { get; private set; }
+ public ProjectEvaluationException (MSBuildProject project, string message): this (project, message, null)
+ {
+ }
+
+ public MSBuildProject Project { get; }
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs
index 742edb3d99..581fef41d4 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/SlnFileFormat.cs
@@ -64,22 +64,20 @@ namespace MonoDevelop.Projects.MSBuild
return obj is Solution;
}
- public Task WriteFile (string file, object obj, bool saveProjects, ProgressMonitor monitor)
+ public async Task WriteFile (string file, object obj, bool saveProjects, ProgressMonitor monitor)
{
- return Task.Run (async delegate {
- Solution sol = (Solution)obj;
+ Solution sol = (Solution)obj;
- try {
- monitor.BeginTask (GettextCatalog.GetString ("Saving solution: {0}", file), 1);
- await WriteFileInternal (file, file, sol, saveProjects, monitor).ConfigureAwait (false);
- } catch (Exception ex) {
- monitor.ReportError (GettextCatalog.GetString ("Could not save solution: {0}", file), ex);
- LoggingService.LogError (GettextCatalog.GetString ("Could not save solution: {0}", file), ex);
- throw;
- } finally {
- monitor.EndTask ();
- }
- });
+ try {
+ monitor.BeginTask (GettextCatalog.GetString ("Saving solution: {0}", file), 1);
+ await WriteFileInternal (file, file, sol, saveProjects, monitor).ConfigureAwait (false);
+ } catch (Exception ex) {
+ monitor.ReportError (GettextCatalog.GetString ("Could not save solution: {0}", file), ex);
+ LoggingService.LogError (GettextCatalog.GetString ("Could not save solution: {0}", file), ex);
+ throw;
+ } finally {
+ monitor.EndTask ();
+ }
}
async Task WriteFileInternal (string file, string sourceFile, Solution solution, bool saveProjects, ProgressMonitor monitor)
@@ -91,7 +89,7 @@ namespace MonoDevelop.Projects.MSBuild
try {
monitor.BeginStep ();
item.SavingSolution = true;
- await item.SaveAsync (monitor);
+ await item.SaveAsync (monitor).ConfigureAwait (false);
} finally {
item.SavingSolution = false;
}
@@ -377,21 +375,19 @@ namespace MonoDevelop.Projects.MSBuild
try {
monitor.BeginTask (string.Format (GettextCatalog.GetString ("Loading solution: {0}"), fileName), 1);
monitor.BeginStep ();
- await sol.OnBeginLoad ();
+ await sol.OnBeginLoad ().ConfigureAwait (false);
var projectLoadMonitor = monitor as ProjectLoadProgressMonitor;
if (projectLoadMonitor != null)
projectLoadMonitor.CurrentSolution = sol;
- await Task.Run (() => {
- sol.ReadSolution (monitor);
- });
+ sol.ReadSolution (monitor);
} catch (Exception ex) {
monitor.ReportError (GettextCatalog.GetString ("Could not load solution: {0}", fileName), ex);
- await sol.OnEndLoad ();
+ await sol.OnEndLoad ().ConfigureAwait (false);
sol.NotifyItemReady ();
monitor.EndTask ();
throw;
}
- await sol.OnEndLoad ();
+ await sol.OnEndLoad ().ConfigureAwait (false);
sol.NotifyItemReady ();
monitor.EndTask ();
return sol;
@@ -533,7 +529,7 @@ namespace MonoDevelop.Projects.MSBuild
}
}
monitor.Step (1);
- });
+ }, TaskScheduler.Default);
loadTasks.Add (ft);
// Limit the number of concurrent tasks. Por solutions with many projects, spawning one thread per
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs
index ffaaef930f..4bb348eddc 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/CompiledAssemblyProject.cs
@@ -215,11 +215,9 @@ namespace MonoDevelop.Projects
public override Task<SolutionItem> LoadSolutionItem (ProgressMonitor monitor, SolutionLoadContext ctx, string fileName, MSBuildFileFormat expectedFormat, string typeGuid, string itemGuid)
{
- return Task<SolutionItem>.Factory.StartNew (delegate {
- CompiledAssemblyProject p = new CompiledAssemblyProject ();
- p.LoadFrom (fileName);
- return p;
- });
+ CompiledAssemblyProject p = new CompiledAssemblyProject ();
+ p.LoadFrom (fileName);
+ return Task.FromResult<SolutionItem> (p);
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MSBuildSerializationExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MSBuildSerializationExtension.cs
index f5b1f1922c..8172ed8212 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MSBuildSerializationExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/MSBuildSerializationExtension.cs
@@ -41,26 +41,22 @@ namespace MonoDevelop.Projects
return false;
}
- public override Task<SolutionItem> LoadSolutionItem (ProgressMonitor monitor, SolutionLoadContext ctx, string fileName, MSBuildFileFormat expectedFormat, string typeGuid, string itemGuid)
+ public override async Task<SolutionItem> LoadSolutionItem (ProgressMonitor monitor, SolutionLoadContext ctx, string fileName, MSBuildFileFormat expectedFormat, string typeGuid, string itemGuid)
{
- return Task.Run (() => {
- foreach (var f in MSBuildFileFormat.GetSupportedFormats ()) {
- if (f.CanReadFile (fileName, typeof(SolutionItem)))
- return MSBuildProjectService.LoadItem (monitor, fileName, f, typeGuid, itemGuid, ctx);
- }
- throw new NotSupportedException ();
- });
+ foreach (var f in MSBuildFileFormat.GetSupportedFormats ()) {
+ if (f.CanReadFile (fileName, typeof(SolutionItem)))
+ return await MSBuildProjectService.LoadItem (monitor, fileName, f, typeGuid, itemGuid, ctx).ConfigureAwait (false);
+ }
+ throw new NotSupportedException ();
}
- public override Task<WorkspaceItem> LoadWorkspaceItem (ProgressMonitor monitor, string fileName)
+ public override async Task<WorkspaceItem> LoadWorkspaceItem (ProgressMonitor monitor, string fileName)
{
- return Task.Run (async () => {
- foreach (var f in MSBuildFileFormat.GetSupportedFormats ()) {
- if (f.CanReadFile (fileName, typeof (WorkspaceItem)))
- return (WorkspaceItem)await f.ReadFile (fileName, typeof (WorkspaceItem), monitor).ConfigureAwait (false);
- }
- throw new NotSupportedException ();
- });
+ foreach (var f in MSBuildFileFormat.GetSupportedFormats ()) {
+ if (f.CanReadFile (fileName, typeof (WorkspaceItem)))
+ return (WorkspaceItem)await f.ReadFile (fileName, typeof (WorkspaceItem), monitor).ConfigureAwait (false);
+ }
+ throw new NotSupportedException ();
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
index 3df66730cc..a8a7c72dd0 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/Project.cs
@@ -415,9 +415,7 @@ namespace MonoDevelop.Projects
protected override Task OnLoad (ProgressMonitor monitor)
{
- return Task.Run (async delegate {
- await LoadAsync (monitor);
- });
+ return LoadAsync (monitor);
}
async Task LoadAsync (ProgressMonitor monitor)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs
index 7997a72146..4b57332e0d 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ProjectService.cs
@@ -54,7 +54,7 @@ namespace MonoDevelop.Projects
TargetFramework defaultTargetFramework;
string defaultPlatformTarget = "anycpu";
- static readonly TargetFrameworkMoniker DefaultTargetFrameworkId = TargetFrameworkMoniker.NET_4_7;
+ static readonly TargetFrameworkMoniker DefaultTargetFrameworkId = TargetFrameworkMoniker.NET_4_7_2;
public const string BuildTarget = "Build";
public const string CleanTarget = "Clean";
@@ -123,7 +123,7 @@ namespace MonoDevelop.Projects
var r = GetObjectReaderForFile (file, typeof(SolutionItem));
if (r == null)
throw new UnknownSolutionItemTypeException ();
- SolutionItem loadedItem = await r.LoadSolutionItem (monitor, ctx, file, format, typeGuid, itemGuid);
+ SolutionItem loadedItem = await Task.Run (() => r.LoadSolutionItem (monitor, ctx, file, format, typeGuid, itemGuid));
if (loadedItem != null) {
loadedItem.NeedsReload = false;
UpdateReadSolutionItemMetadata (metadata, loadedItem);
@@ -216,7 +216,7 @@ namespace MonoDevelop.Projects
var r = GetObjectReaderForFile (file, typeof(WorkspaceItem));
if (r == null)
throw new InvalidOperationException ("Invalid file format: " + file);
- WorkspaceItem item = await r.LoadWorkspaceItem (monitor, fullpath);
+ WorkspaceItem item = await Task.Run (() => r.LoadWorkspaceItem (monitor, fullpath));
if (item != null)
item.NeedsReload = false;
else
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs
index e7514fe8f1..195b692af1 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectExtension.cs
@@ -38,6 +38,8 @@ namespace MonoDevelop.Projects
[ExportProjectModelExtension]
public class SdkProjectExtension : DotNetProjectExtension
{
+ HashSet<(string Name, string Include)> evaluatedItems;
+
MSBuildSdkProject msbuildSdkProject = new MSBuildSdkProject ();
string[] cachedBuildActions;
@@ -53,8 +55,7 @@ namespace MonoDevelop.Projects
/// </summary>
internal static bool FileShouldBeHidden (FilePath file)
{
- return file.HasExtension (".userprefs") ||
- file.FileName == ".DS_Store";
+ return file.HasExtension (".userprefs") || file.HasFileName (".DS_Store");
}
public IEnumerable<string> TargetFrameworks {
@@ -109,6 +110,7 @@ namespace MonoDevelop.Projects
Project.UseFileWatcher = true;
cachedBuildActions = null;
+ evaluatedItems = null;
}
internal protected override void OnWriteProject (ProgressMonitor monitor, MSBuildProject msproject)
@@ -129,36 +131,15 @@ namespace MonoDevelop.Projects
{
var sourceFiles = await base.OnGetSourceFiles (monitor, configuration);
- return AddMissingProjectFiles (sourceFiles, configuration);
- }
-
- ImmutableArray<ProjectFile> AddMissingProjectFiles (ImmutableArray<ProjectFile> files, ConfigurationSelector configuration)
- {
- ImmutableArray<ProjectFile>.Builder missingFiles = null;
- foreach (ProjectFile existingFile in Project.Files.Where (file => file.BuildAction == BuildAction.Compile)) {
- if (!files.Any (file => file.FilePath == existingFile.FilePath)) {
- if (missingFiles == null)
- missingFiles = ImmutableArray.CreateBuilder<ProjectFile> ();
- missingFiles.Add (existingFile);
- }
- }
-
// Ensure generated assembly info file is available to type system. It is created in the obj
// directory and is excluded from the project with a wildcard exclude but the type system needs it to
// ensure the project's assembly information is correct to prevent diagnostic errors.
var generatedAssemblyInfoFile = GetGeneratedAssemblyInfoFile (configuration);
if (generatedAssemblyInfoFile != null) {
- if (missingFiles == null)
- missingFiles = ImmutableArray.CreateBuilder<ProjectFile> ();
- missingFiles.Add (generatedAssemblyInfoFile);
+ return sourceFiles.Add (generatedAssemblyInfoFile);
}
- if (missingFiles == null)
- return files;
-
- missingFiles.Capacity = missingFiles.Count + files.Length;
- missingFiles.AddRange (files);
- return missingFiles.MoveToImmutable ();
+ return sourceFiles;
}
ProjectFile GetGeneratedAssemblyInfoFile (ConfigurationSelector configuration)
@@ -185,14 +166,23 @@ namespace MonoDevelop.Projects
// project file is being saved.
}
- bool IsFSharpSdkProject ()
+ bool? isFSharpSdkProject;
+ bool IsLegacyFSharpSdkProject ()
{
- var sdks = Project.MSBuildProject.GetReferencedSDKs ();
- for (var i = 0; i < sdks.Length; i++) {
- if (sdks [i].Contains ("FSharp"))
- return true;
+ if (isFSharpSdkProject is null) {
+ isFSharpSdkProject = ContainsFSharpSdk (Project.MSBuildProject.GetReferencedSDKs ());
+ }
+
+ return isFSharpSdkProject.Value;
+
+ static bool ContainsFSharpSdk (string[] sdks)
+ {
+ for (var i = 0; i < sdks.Length; i++) {
+ if (sdks [i].Contains ("FSharp"))
+ return true;
+ }
+ return false;
}
- return false;
}
internal protected override bool OnGetSupportsImportedItem (IMSBuildItemEvaluated buildItem)
@@ -200,7 +190,7 @@ namespace MonoDevelop.Projects
if (!IsBuildActionSupported (buildItem.Name))
return false;
- if (IsFSharpSdkProject ()) {
+ if (IsLegacyFSharpSdkProject ()) {
// Ignore imported F# files. F# files are defined in the main project.
// This prevents duplicate F# files when a new project is first created.
if (buildItem.Include.EndsWith (".fs", StringComparison.OrdinalIgnoreCase))
@@ -210,11 +200,15 @@ namespace MonoDevelop.Projects
if (IsFromSharedProject (buildItem))
return false;
- // HACK: Remove any imported items that are not in the EvaluatedItems
- // This may happen if a condition excludes the item. All items passed to the
- // OnGetSupportsImportedItem are from the EvaluatedItemsIgnoringCondition
- return Project.MSBuildProject.EvaluatedItems
- .Any (item => item.IsImported && item.Name == buildItem.Name && item.Include == buildItem.Include);
+ evaluatedItems ??= CreateEvaluatedItemsCache (Project.MSBuildProject);
+ return evaluatedItems.Contains ((buildItem.Name, buildItem.Include));
+
+ static HashSet<(string, string)> CreateEvaluatedItemsCache (MSBuildProject project)
+ => new HashSet<(string Name, string Include)> (
+ project.EvaluatedItems
+ .Where (x => x.IsImported)
+ .Select (x => (x.Name, x.Include))
+ );
}
/// <summary>
@@ -262,6 +256,8 @@ namespace MonoDevelop.Projects
internal protected override async Task OnReevaluateProject (ProgressMonitor monitor)
{
await base.OnReevaluateProject (monitor);
+
+ isFSharpSdkProject = null;
UpdateHiddenFiles (Project.Files);
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectReader.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectReader.cs
index 6765edf762..2d42a1576f 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectReader.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SdkProjectReader.cs
@@ -96,15 +96,13 @@ namespace MonoDevelop.Projects
return null;
}
- public override Task<SolutionItem> LoadSolutionItem (ProgressMonitor monitor, SolutionLoadContext ctx, string fileName, MSBuildFileFormat expectedFormat, string typeGuid, string itemGuid)
+ public override async Task<SolutionItem> LoadSolutionItem (ProgressMonitor monitor, SolutionLoadContext ctx, string fileName, MSBuildFileFormat expectedFormat, string typeGuid, string itemGuid)
{
- return Task.Run (() => {
- if (CanRead (fileName, typeof (SolutionItem))) {
- return MSBuildProjectService.LoadItem (monitor, fileName, MSBuildFileFormat.VS2012, typeGuid, itemGuid, ctx);
- }
+ if (CanRead (fileName, typeof (SolutionItem))) {
+ return await MSBuildProjectService.LoadItem (monitor, fileName, MSBuildFileFormat.VS2012, typeGuid, itemGuid, ctx);
+ }
- throw new NotSupportedException ();
- });
+ throw new NotSupportedException ();
}
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
index 8dce5f1327..2a9c0c96e3 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/SolutionItem.cs
@@ -460,7 +460,7 @@ namespace MonoDevelop.Projects
if (ItemExtension.OnCheckHasSolutionData () && !SavingSolution && ParentSolution != null) {
// The project has data that has to be saved in the solution, but the solution is not being saved. Do it now.
- await SolutionFormat.SlnFileFormat.WriteFile (ParentSolution.FileName, ParentSolution, false, monitor);
+ await Task.Run (() => SolutionFormat.SlnFileFormat.WriteFile (ParentSolution.FileName, ParentSolution, false, monitor));
ParentSolution.NeedsReload = false;
}
}
@@ -1232,12 +1232,12 @@ namespace MonoDevelop.Projects
protected virtual Task OnLoad (ProgressMonitor monitor)
{
- return Task.FromResult (0);
+ return Task.CompletedTask;
}
protected internal virtual Task OnSave (ProgressMonitor monitor)
{
- return Task.FromResult (0);
+ return Task.CompletedTask;
}
public FilePath GetAbsoluteChildPath (FilePath relPath)
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs
index 639c96b249..7b4dec5b75 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceItem.cs
@@ -276,7 +276,7 @@ namespace MonoDevelop.Projects
FileService.RequestFileEdit (f);
try {
fileStatusTracker.BeginSave ();
- await ItemExtension.Save (monitor);
+ await Task.Run (() => ItemExtension.Save (monitor));
await OnSaveUserProperties (); // Call the virtual to avoid the lock
OnSaved (new WorkspaceItemEventArgs (this));
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectReader.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectReader.cs
index 9c0a453544..b205558a76 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectReader.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceObjectReader.cs
@@ -41,12 +41,12 @@ namespace MonoDevelop.Projects
public virtual Task<SolutionItem> LoadSolutionItem (ProgressMonitor monitor, SolutionLoadContext ctx, string fileName, MSBuildFileFormat expectedFormat, string typeGuid, string itemGuid)
{
- throw new NotSupportedException ();
+ return Task.FromException<SolutionItem> (new NotSupportedException ());
}
public virtual Task<WorkspaceItem> LoadWorkspaceItem (ProgressMonitor monitor, string fileName)
{
- throw new NotSupportedException ();
+ return Task.FromException<WorkspaceItem> (new NotSupportedException ());
}
}
diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceSerializationExtension.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceSerializationExtension.cs
index f96243af37..7e4c748ab5 100644
--- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceSerializationExtension.cs
+++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/WorkspaceSerializationExtension.cs
@@ -45,13 +45,11 @@ namespace MonoDevelop.Projects
return false;
}
- public override Task<WorkspaceItem> LoadWorkspaceItem (ProgressMonitor monitor, string fileName)
+ public override async Task<WorkspaceItem> LoadWorkspaceItem (ProgressMonitor monitor, string fileName)
{
- return Task.Run (async () => {
- var workspaceItem = ReadWorkspaceItemFile (fileName, monitor);
- await workspaceItem.LoadUserProperties ().ConfigureAwait (false);
- return workspaceItem;
- });
+ var workspaceItem = ReadWorkspaceItemFile (fileName, monitor);
+ await workspaceItem.LoadUserProperties ().ConfigureAwait (false);
+ return workspaceItem;
}
WorkspaceItem ReadWorkspaceItemFile (FilePath fileName, ProgressMonitor monitor)