Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more known legacy TFMs #218

Merged
merged 9 commits into from
Apr 27, 2024
Merged
91 changes: 91 additions & 0 deletions MonoDevelop.MSBuild.Tests/FrameworkInfoTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using MonoDevelop.MSBuild.Schema;

using NUnit.Framework;

namespace MonoDevelop.MSBuild.Tests;

[TestFixture]
class FrameworkInfoTests
{
[TestCase ("net48")]
[TestCase ("net4.8")]
[TestCase ("sl3")]
[TestCase ("wp8")]
[TestCase ("uap10.0.1234")]
[TestCase ("uap10.0")]
[TestCase ("net8.0-android")]
[TestCase ("net8.0")]
public void ValidFrameworkName (string name)
{
var validationResult = FrameworkInfoProvider.Instance.ValidateFrameworkShortName (name, out _, out _, out _, out _, out _);
Assert.AreEqual (FrameworkNameValidationResult.OK, validationResult);
}

[TestCase ("foo")]
[TestCase ("foo1.0")]
public void UnknownIdentifier (string name)
{
var validationResult = FrameworkInfoProvider.Instance.ValidateFrameworkShortName (name, out _, out _, out _, out _, out _);
Assert.AreEqual (FrameworkNameValidationResult.UnknownIdentifier, validationResult);
}

[TestCase ("net485")]
[TestCase ("sl6.0")]
public void UnknownVersion (string name)
{
var validationResult = FrameworkInfoProvider.Instance.ValidateFrameworkShortName (name, out _, out _, out _, out _, out _);
Assert.AreEqual (FrameworkNameValidationResult.UnknownVersion, validationResult);
}

[TestCase ("net481-client")]
[TestCase ("net35-bad")]
public void UnknownProfile (string name)
{
var validationResult = FrameworkInfoProvider.Instance.ValidateFrameworkShortName (name, out _, out _, out _, out _, out _);
Assert.AreEqual (FrameworkNameValidationResult.UnknownProfile, validationResult);
}

[TestCase ("net6.0-fridge")]
public void UnknownPlatform (string name)
{
var validationResult = FrameworkInfoProvider.Instance.ValidateFrameworkShortName (name, out _, out _, out _, out _, out _);
Assert.AreEqual (FrameworkNameValidationResult.UnknownPlatform, validationResult);
}

[TestCase ("net481", ".NET Framework 4.8.1")]
[TestCase ("net4.8.1", ".NET Framework 4.8.1")]
[TestCase ("wpa81", "Windows Phone (UWP) 8.1")]
[TestCase ("net6.0-android9000.0", ".NET 6.0 with platform-specific APIs for Android 9000.0")]
[TestCase ("net6.0-android", ".NET 6.0 with platform-specific APIs for Android 31.0")]
[TestCase ("net6.0-android32.0", ".NET 6.0 with platform-specific APIs for Android 32.0")]
[TestCase ("net7.0-android", ".NET 7.0 with platform-specific APIs for Android 33.0")]
[TestCase ("net6.0", ".NET 6.0")]
public void FrameworkDescription (string tfm, string description)
{
var fx = FrameworkInfoProvider.TryGetFrameworkInfo (tfm);
Assert.IsNotNull (fx);

var actualDescription = FrameworkInfoProvider.GetDisplayDescription (fx.Reference);
Assert.AreEqual (description, actualDescription);
}

[TestCase ("net481", ".NETFramework,Version=v4.8.1")]
[TestCase ("net4.8.1", ".NETFramework,Version=v4.8.1")]
[TestCase ("wpa81", "WindowsPhoneApp,Version=v8.1")]
[TestCase ("net6.0-android9000.0", ".NETCoreApp,Version=v6.0 | Android 9000.0")]
[TestCase ("net6.0-android", ".NETCoreApp,Version=v6.0 | Android 31.0")]
[TestCase ("net6.0-android32.0", ".NETCoreApp,Version=v6.0 | Android 32.0")]
[TestCase ("net7.0-android", ".NETCoreApp,Version=v7.0 | Android 33.0")]
[TestCase ("net6.0", ".NETCoreApp,Version=v6.0")]
public void FrameworkTitle (string tfm, string description)
{
var fx = FrameworkInfoProvider.TryGetFrameworkInfo (tfm);
Assert.IsNotNull (fx);

var actualDescription = FrameworkInfoProvider.GetDisplayTitle (fx.Reference);
Assert.AreEqual (description, actualDescription);
}
}
7 changes: 7 additions & 0 deletions MonoDevelop.MSBuild/Language/CoreDiagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,13 @@ class CoreDiagnostics
"The target framework `{0}` has an unknown target platform `{1}`",
MSBuildDiagnosticSeverity.Warning);

public const string TargetFrameworkHasUnknownProfile_Id = nameof (TargetFrameworkHasUnknownProfile);
public static readonly MSBuildDiagnosticDescriptor TargetFrameworkHasUnknownProfile = new (
TargetFrameworkHasUnknownProfile_Id,
"Unknown framework profile",
"The target framework `{0}` has unknown profile `{1}`",
MSBuildDiagnosticSeverity.Warning);

public const string TargetFrameworkHasUnknownTargetPlatformVersion_Id = nameof (TargetFrameworkHasUnknownTargetPlatformVersion);
public static readonly MSBuildDiagnosticDescriptor TargetFrameworkHasUnknownTargetPlatformVersion = new (
TargetFrameworkHasUnknownTargetPlatformVersion_Id,
Expand Down
9 changes: 6 additions & 3 deletions MonoDevelop.MSBuild/Language/MSBuildDocumentValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ void VisitPureLiteral (MSBuildElementSyntax elementSymbol, MSBuildAttributeSynta
}
break;
case MSBuildValueKind.TargetFramework:
switch (FrameworkInfoProvider.Instance.ValidateFrameworkShortName (value, out var frameworkComponent, out var versionComponent, out var platformComponent, out var platformVersionComponent)) {
switch (FrameworkInfoProvider.Instance.ValidateFrameworkShortName (value, out var frameworkComponent, out var versionComponent, out var platformComponent, out var profileComponent, out var platformVersionComponent)) {
case FrameworkNameValidationResult.OK:
break;
case FrameworkNameValidationResult.Malformed:
Expand All @@ -750,13 +750,16 @@ void VisitPureLiteral (MSBuildElementSyntax elementSymbol, MSBuildAttributeSynta
case FrameworkNameValidationResult.UnknownPlatform:
AddErrorWithArgs (CoreDiagnostics.TargetFrameworkHasUnknownTargetPlatform, value, platformComponent);
break;
case FrameworkNameValidationResult.UnknownProfile:
AddErrorWithArgs (CoreDiagnostics.TargetFrameworkHasUnknownProfile, value, profileComponent);
break;
case FrameworkNameValidationResult.UnknownPlatformVersion:
AddErrorWithArgs (CoreDiagnostics.TargetFrameworkHasUnknownTargetPlatformVersion, value, platformVersionComponent, platformComponent);
break;
}
break;
case MSBuildValueKind.TargetFrameworkIdentifier:
if (!FrameworkInfoProvider.Instance.IsFrameworkIdentifierValid (value)) {
if (!FrameworkInfoProvider.Instance.IsKnownFrameworkIdentifier (value)) {
AddErrorWithArgs (CoreDiagnostics.UnknownTargetFrameworkIdentifier, value);
}
break;
Expand All @@ -769,7 +772,7 @@ void VisitPureLiteral (MSBuildElementSyntax elementSymbol, MSBuildAttributeSynta
if (Document is MSBuildRootDocument d && d.Frameworks.Count > 0) {
bool foundMatch = false;
foreach (var fx in d.Frameworks) {
if (FrameworkInfoProvider.AreVersionsEquivalent (fx.Version, fxv) && FrameworkInfoProvider.Instance.IsFrameworkVersionValid (fx.Framework, fxv)) {
if (FrameworkInfoProvider.AreVersionsEquivalent (fx.Version, fxv) && FrameworkInfoProvider.Instance.IsKnownFrameworkVersion (fx.Framework, fxv)) {
foundMatch = true;
}
}
Expand Down
9 changes: 6 additions & 3 deletions MonoDevelop.MSBuild/Language/Typesystem/FrameworkInfo.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
#nullable enable

using NuGet.Frameworks;

Expand All @@ -11,14 +11,17 @@ namespace MonoDevelop.MSBuild.Language.Typesystem
// a shortname, identifier, version or profile
// the "name" is the piece that's being represented and the reference is the
// full ID, or as close to it as we have
class FrameworkInfo : BaseSymbol
class FrameworkInfo : BaseSymbol, IDeprecatable
{
public FrameworkInfo (string name, NuGetFramework reference)
public FrameworkInfo (string name, NuGetFramework reference, string? deprecationMessage = null)
: base (name, null)
{
Reference = reference;
DeprecationMessage = deprecationMessage;
}

public NuGetFramework Reference { get; }

public string? DeprecationMessage { get; }
}
}
4 changes: 2 additions & 2 deletions MonoDevelop.MSBuild/Schema/DescriptionFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ string GetDesc (string id) => string.Format (
}
break;
case FrameworkInfo fxi:
return FrameworkInfoProvider.GetDescription (fxi.Reference);
return FrameworkInfoProvider.GetDisplayDescription (fxi.Reference);
}
}

Expand Down Expand Up @@ -94,7 +94,7 @@ public static (string kind, string name) GetTitle (ISymbol info)
case FileOrFolderInfo value:
return (value.IsFolder? "folder" : "file", info.Name);
case FrameworkInfo fxi:
return ("framework", FrameworkInfoProvider.Instance.FormatNameForTitle (fxi.Reference));
return ("framework", FrameworkInfoProvider.GetDisplayTitle (fxi.Reference));
case TaskParameterInfo tpi:
return ("parameter", tpi.Name);
case FunctionInfo fi:
Expand Down
97 changes: 97 additions & 0 deletions MonoDevelop.MSBuild/Schema/FrameworkInfoProvider.PlatformId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace MonoDevelop.MSBuild.Schema
{
partial class FrameworkInfoProvider
{
static class KnownPlatform
{
public const string Windows = "Windows";
public const string Android = "Android";
public const string iOS = "iOS";
public const string macOS = "macOS";
public const string tvOS = "tvOS";
public const string MacCatalyst = "MacCatalyst";
public const string Tizen = "Tizen";
public const string Browser = "Browser";

static class LowerId
{
public const string Windows = "windows";
public const string Android = "android";
public const string iOS = "ios";
public const string macOS = "macos";
public const string tvOS = "tvos";
public const string MacCatalyst = "maccatalyst";
public const string Tizen = "tizen";
public const string Browser = "browser";
}

public static string ToLowerCase (string platform) => platform switch {
Windows => LowerId.Windows,
Android => LowerId.Android,
iOS => LowerId.iOS,
macOS => LowerId.macOS,
tvOS => LowerId.tvOS,
MacCatalyst => LowerId.MacCatalyst,
Tizen => LowerId.Tizen,
Browser => LowerId.Browser,
_ => platform.ToLowerInvariant ()
};

public static string ToCanonicalCase (string platform)
{
return CanonicalCaseFromLower (platform)
?? CanonicalCaseFromLower (platform.ToLowerInvariant ())
?? platform;

static string? CanonicalCaseFromLower (string platform) => platform switch {
LowerId.Windows => Windows,
LowerId.Android => Android,
LowerId.iOS => iOS,
LowerId.macOS => macOS,
LowerId.tvOS => tvOS,
LowerId.MacCatalyst => MacCatalyst,
LowerId.Tizen => Tizen,
LowerId.Browser => Browser,
_ => null
};
}

public static bool TryGetDefaultPlatformVersion (int netcoreappMajorVersion, string platform, [NotNullWhen (true)] out Version? defaultPlatformVersion)
{
return defaultPlatformVersions.TryGetValue ((netcoreappMajorVersion, ToLowerCase (platform)), out defaultPlatformVersion);
}

static readonly Dictionary<(int, string), Version> defaultPlatformVersions = new () {
{ (6, LowerId.Android), new Version (31, 0) },
{ (7, LowerId.Android), new Version (33, 0) },
{ (8, LowerId.Android), new Version (34, 0) },
{ (6, LowerId.iOS), new Version (15, 0) },
{ (7, LowerId.iOS), new Version (16, 1) },
{ (8, LowerId.iOS), new Version (17, 2) },
{ (5, LowerId.MacCatalyst), new Version (15, 0) },
{ (7, LowerId.MacCatalyst), new Version (16, 1) },
{ (8, LowerId.MacCatalyst), new Version (17, 2) },
{ (6, LowerId.macOS), new Version (12, 0) },
{ (7, LowerId.macOS), new Version (13, 0) },
{ (8, LowerId.macOS), new Version (14, 2) },
{ (6, LowerId.tvOS), new Version (15, 1) },
{ (7, LowerId.tvOS), new Version (16, 1) },
{ (8, LowerId.tvOS), new Version (17, 1) },
{ (7, LowerId.Tizen), new Version (7, 0) },
{ (8, LowerId.Tizen), new Version (8, 0) },
{ (6, LowerId.Windows), new Version (7, 0) },
{ (7, LowerId.Windows), new Version (7, 0) },
{ (8, LowerId.Windows), new Version (7, 0) },
};
}
}
}
Loading
Loading