| File: FindInvalidProjectReferences.cs | Web Access |
| Project: src\msbuild\src\Tasks\Microsoft.Build.Tasks.csproj (Microsoft.Build.Tasks.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Text.RegularExpressions; using Microsoft.Build.Framework; #nullable disable namespace Microsoft.Build.Tasks { /// <summary> /// Returns the reference assembly paths to the various frameworks /// </summary> [MSBuildMultiThreadableTask] public partial class FindInvalidProjectReferences : TaskExtension { #region Fields private const string PlatformMonikerFormatPattern = @"(?<PLATFORMIDENTITY>^[^,]*),\s*Version=(?<PLATFORMVERSION>.*)"; /// <summary> /// Regex for breaking up the platform moniker /// Example: XNA, Version=8.0 /// </summary> #if NET [GeneratedRegex(PlatformMonikerFormatPattern, RegexOptions.IgnoreCase)] private static partial Regex PlatformMonikerRegex { get; } #else private static Regex PlatformMonikerRegex { get; } = new Regex(PlatformMonikerFormatPattern, RegexOptions.IgnoreCase); #endif /// <summary> /// Reference moniker metadata /// </summary> private const string ReferencePlatformMonikerMetadata = "TargetPlatformMoniker"; /// <summary> /// SimpleName group /// </summary> private const string PlatformSimpleNameGroup = "PLATFORMIDENTITY"; /// <summary> /// Version group /// </summary> private const string PlatformVersionGroup = "PLATFORMVERSION"; #endregion #region Properties /// <summary> /// List of Platform monikers for each referenced project /// </summary> public ITaskItem[] ProjectReferences { get; set; } /// <summary> /// Target platform version of the current project /// </summary> [Required] public string TargetPlatformVersion { get; set; } /// <summary> /// Target platform identifier of the current project /// </summary> [Required] public string TargetPlatformIdentifier { get; set; } /// <summary> /// Invalid references to be unresolved /// </summary> [Output] public ITaskItem[] InvalidReferences { get; private set; } #endregion #region ITask Members /// <summary> /// Execute the task. /// </summary> public override bool Execute() { var invalidReferences = new List<ITaskItem>(); Version.TryParse(TargetPlatformVersion, out Version targetPlatformVersionAsVersion); if (ProjectReferences != null) { foreach (ITaskItem item in ProjectReferences) { string referenceIdentity = item.ItemSpec; string referencePlatformMoniker = item.GetMetadata(ReferencePlatformMonikerMetadata); // For each moniker, compare version, issue localized message if the referenced project targets // a platform with version higher than the current project and make the reference invalid by adding it to // an invalid reference list output if (ParseMoniker(referencePlatformMoniker, out _, out Version version)) { if (targetPlatformVersionAsVersion < version) { Log.LogWarningWithCodeFromResources("FindInvalidProjectReferences.WarnWhenVersionIsIncompatible", TargetPlatformIdentifier, TargetPlatformVersion, referenceIdentity, referencePlatformMoniker); invalidReferences.Add(item); } } } } InvalidReferences = invalidReferences.ToArray(); return true; } /// <summary> /// Take the identity and the version of a platform moniker /// </summary> private static bool ParseMoniker(string reference, out string platformIdentity, out Version platformVersion) { Match match = PlatformMonikerRegex.Match(reference); platformIdentity = String.Empty; bool parsedVersion = false; platformVersion = null; if (match.Success) { platformIdentity = match.Groups[PlatformSimpleNameGroup].Value.Trim(); string rawVersion = match.Groups[PlatformVersionGroup].Value.Trim(); parsedVersion = Version.TryParse(rawVersion, out platformVersion); } return platformIdentity.Length > 0 && parsedVersion; } #endregion } }