public static IReadOnlyList <BaseInfo> GetValueCompletions( MSBuildValueKind kind, MSBuildRootDocument doc, MSBuildResolveResult rr = null, ExpressionNode triggerExpression = null) { var simple = kind.GetSimpleValues(true); if (simple != null) { return(simple); } switch (kind) { case MSBuildValueKind.TaskOutputParameterName: return(doc.GetTaskParameters(rr.ParentName).Where(p => p.IsOutput).ToList()); case MSBuildValueKind.TargetName: return(doc.GetTargets().ToList()); case MSBuildValueKind.PropertyName: return(doc.GetProperties(true).ToList()); case MSBuildValueKind.ItemName: return(doc.GetItems().ToList()); case MSBuildValueKind.TargetFramework: return(FrameworkInfoProvider.Instance.GetFrameworksWithShortNames().ToList()); case MSBuildValueKind.TargetFrameworkIdentifier: return(FrameworkInfoProvider.Instance.GetFrameworkIdentifiers().ToList()); case MSBuildValueKind.TargetFrameworkVersion: return(doc.Frameworks.Select(f => f.Framework).Distinct().SelectMany( id => FrameworkInfoProvider.Instance.GetFrameworkVersions(id) ).Distinct().ToList()); case MSBuildValueKind.TargetFrameworkProfile: return(doc.Frameworks.SelectMany( tfm => FrameworkInfoProvider.Instance.GetFrameworkProfiles(tfm.Framework, tfm.Version) ).Distinct().ToList()); case MSBuildValueKind.Configuration: return(doc.GetConfigurations().Select(c => new ConstantInfo(c, "")).ToList()); case MSBuildValueKind.Platform: return(doc.GetPlatforms().Select(c => new ConstantInfo(c, "")).ToList()); } var fileCompletions = GetFilenameCompletions(kind, doc, triggerExpression, 0, rr); if (fileCompletions != null) { return(fileCompletions); } return(null); }
void VisitPureLiteral(XElement element, ITypedSymbol valueDescriptor, MSBuildValueKind inferredKind, ExpressionText node) { string value = node.GetUnescapedValue(); rr.ReferenceOffset = node.Offset; rr.ReferenceLength = node.Value.Length; rr.Reference = value; switch (inferredKind) { case MSBuildValueKind.TaskOutputParameterName: rr.ReferenceKind = MSBuildReferenceKind.TaskParameter; return; case MSBuildValueKind.TargetName: rr.ReferenceKind = MSBuildReferenceKind.Target; return; case MSBuildValueKind.NuGetID: rr.ReferenceKind = MSBuildReferenceKind.NuGetID; return; case MSBuildValueKind.PropertyName: rr.ReferenceKind = MSBuildReferenceKind.Property; return; case MSBuildValueKind.ItemName: rr.ReferenceKind = MSBuildReferenceKind.Item; return; case MSBuildValueKind.TaskName: rr.ReferenceKind = MSBuildReferenceKind.Task; return; case MSBuildValueKind.TargetFramework: rr.ReferenceKind = MSBuildReferenceKind.TargetFramework; return; case MSBuildValueKind.TargetFrameworkIdentifier: rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkIdentifier; return; case MSBuildValueKind.TargetFrameworkVersion: rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkVersion; return; case MSBuildValueKind.TargetFrameworkProfile: rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkProfile; return; case MSBuildValueKind.MetadataName: //this is used for KeepMetadata/RemoveMetadata. //reasonable to resolve from first item in include. var itemName = MSBuildMetadataReferenceCollector.GetIncludeExpression(element) .WithAllDescendants() .OfType <ExpressionItemName> () .FirstOrDefault(); if (itemName != null) { rr.Reference = (itemName.Name, value); rr.ReferenceKind = MSBuildReferenceKind.Metadata; } return; } var knownVals = (IReadOnlyList <ISymbol>)valueDescriptor.CustomType?.Values ?? inferredKind.GetSimpleValues(true); if (knownVals != null && knownVals.Count != 0) { foreach (var kv in knownVals) { if (string.Equals(kv.Name, value, StringComparison.OrdinalIgnoreCase)) { rr.ReferenceKind = MSBuildReferenceKind.KnownValue; rr.Reference = kv; return; } } } }
//note: the value is unescaped, so offsets within it are not valid void VisitPureLiteral(ValueInfo info, MSBuildValueKind kind, string value, int offset) { IReadOnlyList <ConstantInfo> knownVals = info.Values ?? kind.GetSimpleValues(false); if (knownVals != null && knownVals.Count != 0) { foreach (var kv in knownVals) { if (string.Equals(kv.Name, value, StringComparison.OrdinalIgnoreCase)) { return; } } AddError($"Unknown value '{value}'"); return; } switch (kind) { case MSBuildValueKind.Guid: case MSBuildValueKind.ProjectKindGuid: if (!Guid.TryParseExact(value, "B", out _)) { AddError("Invalid GUID value"); } break; case MSBuildValueKind.Int: if (!long.TryParse(value, out _)) { AddError("Invalid integer value"); } break; case MSBuildValueKind.Bool: if (!bool.TryParse(value, out _)) { AddError("Invalid boolean value"); } break; case MSBuildValueKind.Url: if (!Uri.TryCreate(value, UriKind.Absolute, out _)) { AddError("Invalid URL"); } break; case MSBuildValueKind.Version: if (!Version.TryParse(value, out _)) { AddError("Invalid version"); } break; case MSBuildValueKind.TargetName: if (Document.GetSchemas().GetTarget(value) == null) { AddWarning("Target is not defined"); } break; case MSBuildValueKind.PropertyName: if (Document.GetSchemas().GetProperty(value) == null) { AddWarning("Unknown property name"); } break; case MSBuildValueKind.ItemName: if (Document.GetSchemas().GetItem(value) == null) { AddWarning("Unknown item name"); } break; case MSBuildValueKind.Lcid: if (int.TryParse(value, out int lcid) && lcid > 0) { try { CultureInfo.GetCultureInfo(lcid); } catch (CultureNotFoundException) { AddError("Unknown LCID"); } } else { AddError("Invalid LCID"); } break; } void AddError(string e) => this.AddError(e, offset, value.Length); void AddWarning(string e) => this.AddWarning(e, offset, value.Length); }
public static IEnumerable <ISymbol> GetValueCompletions( MSBuildValueKind kind, MSBuildRootDocument doc, MSBuildResolveResult rr = null, ExpressionNode triggerExpression = null) { var simple = kind.GetSimpleValues(true); if (simple != null) { return(simple); } switch (kind) { case MSBuildValueKind.TaskOutputParameterName: return(doc.GetTaskParameters(rr.ParentName).Where(p => p.IsOutput).ToList()); case MSBuildValueKind.TargetName: return(doc.GetTargets().ToList()); case MSBuildValueKind.PropertyName: return(doc.GetProperties(true).ToList()); case MSBuildValueKind.ItemName: return(doc.GetItems().ToList()); case MSBuildValueKind.TargetFramework: return(FrameworkInfoProvider.Instance.GetFrameworksWithShortNames().ToList()); case MSBuildValueKind.TargetFrameworkIdentifier: return(FrameworkInfoProvider.Instance.GetFrameworkIdentifiers().ToList()); case MSBuildValueKind.TargetFrameworkVersion: return(doc.Frameworks.Select(f => f.Framework).Distinct().SelectMany( id => FrameworkInfoProvider.Instance.GetFrameworkVersions(id) ).Distinct().ToList()); case MSBuildValueKind.TargetFrameworkProfile: return(doc.Frameworks.SelectMany( tfm => FrameworkInfoProvider.Instance.GetFrameworkProfiles(tfm.Framework, tfm.Version) ).Distinct().ToList()); case MSBuildValueKind.Configuration: return(doc.GetConfigurations().Select(c => new ConstantSymbol(c, "", MSBuildValueKind.Configuration)).ToList()); case MSBuildValueKind.Platform: return(doc.GetPlatforms().Select(c => new ConstantSymbol(c, "", MSBuildValueKind.Platform)).ToList()); case MSBuildValueKind.Condition: //FIXME: relax this a bit if (triggerExpression != null && triggerExpression is ExpressionText t && t.Length == 0) { return(Builtins.ConditionFunctions.Values); } break; } var fileCompletions = GetFilenameCompletions(kind, doc, triggerExpression, 0, rr); if (fileCompletions != null) { return(fileCompletions); } return(null); }
//note: the value is unescaped, so offsets within it are not valid void VisitPureLiteral(ValueInfo info, MSBuildValueKind kind, string value, int offset) { IReadOnlyList <ConstantInfo> knownVals = info.Values ?? kind.GetSimpleValues(false); if (knownVals != null && knownVals.Count != 0) { foreach (var kv in knownVals) { if (string.Equals(kv.Name, value, StringComparison.OrdinalIgnoreCase)) { return; } } AddErrorWithArgs(CoreDiagnostics.UnknownValue, DescriptionFormatter.GetKindNoun(info), info.Name, value); return; } switch (kind) { case MSBuildValueKind.Guid: case MSBuildValueKind.ProjectKindGuid: if (!Guid.TryParseExact(value, "B", out _)) { AddErrorWithArgs(CoreDiagnostics.InvalidGuid, value); } break; case MSBuildValueKind.Int: if (!long.TryParse(value, out _)) { AddErrorWithArgs(CoreDiagnostics.InvalidInteger, value); } break; case MSBuildValueKind.Bool: if (!bool.TryParse(value, out _)) { AddErrorWithArgs(CoreDiagnostics.InvalidBool, value); } break; case MSBuildValueKind.Url: if (!Uri.TryCreate(value, UriKind.Absolute, out _)) { AddErrorWithArgs(CoreDiagnostics.InvalidUrl, value); } break; case MSBuildValueKind.Version: if (!Version.TryParse(value, out _)) { AddErrorWithArgs(CoreDiagnostics.InvalidVersion, value); } break; /* * FIXME: these won't work as-is, as inference will add them to the schema * case MSBuildValueKind.TargetName: * if (Document.GetSchemas ().GetTarget (value) == null) { * AddErrorWithArgs (CoreDiagnostics.UndefinedTarget, value); * } * break; * case MSBuildValueKind.PropertyName: * if (Document.GetSchemas ().GetProperty (value) == null) { * AddErrorWithArgs (CoreDiagnostics.UnknownProperty, value); * } * break; * case MSBuildValueKind.ItemName: * if (Document.GetSchemas ().GetItem (value) == null) { * AddErrorWithArgs (CoreDiagnostics.UnknownProperty, value); * } * break; */ case MSBuildValueKind.Lcid: if (int.TryParse(value, out int lcid) && lcid > 0) { try { CultureInfo.GetCultureInfo(lcid); } catch (CultureNotFoundException) { AddErrorWithArgs(CoreDiagnostics.UnknownLcid, value); } } else { AddErrorWithArgs(CoreDiagnostics.InvalidLcid, value); } break; case MSBuildValueKind.TargetFramework: if (!FrameworkInfoProvider.Instance.IsFrameworkShortNameValid(value)) { AddErrorWithArgs(CoreDiagnostics.UnknownTargetFramework, value); } break; case MSBuildValueKind.TargetFrameworkIdentifier: if (!FrameworkInfoProvider.Instance.IsFrameworkIdentifierValid(value)) { AddErrorWithArgs(CoreDiagnostics.UnknownTargetFrameworkIdentifier, value); } break; case MSBuildValueKind.TargetFrameworkVersion: { if (!Version.TryParse(value.TrimStart('v', 'V'), out Version fxv)) { AddErrorWithArgs(CoreDiagnostics.InvalidVersion, value); break; } fxv = new Version(Math.Max(fxv.Major, 0), Math.Max(fxv.Minor, 0), Math.Max(fxv.Revision, 0), Math.Max(fxv.Build, 0)); 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)) { foundMatch = true; } } if (!foundMatch) { AddErrorWithArgs(CoreDiagnostics.UnknownTargetFrameworkVersion, value, d.Frameworks[0].Framework); } } break; } case MSBuildValueKind.TargetFrameworkProfile: { if (Document is MSBuildRootDocument d && d.Frameworks.Count > 0) { bool foundMatch = false; foreach (var fx in d.Frameworks) { if (fx.Profile == value && FrameworkInfoProvider.Instance.IsFrameworkProfileValid(fx.Framework, fx.Version, value)) { foundMatch = true; } } if (!foundMatch) { AddErrorWithArgs(CoreDiagnostics.UnknownTargetFrameworkProfile, value, d.Frameworks[0].Framework, d.Frameworks[0].Version); } } break; } } void AddError(MSBuildDiagnosticDescriptor d) => Document.Diagnostics.Add(d, new TextSpan(offset, value.Length)); void AddErrorWithArgs(MSBuildDiagnosticDescriptor d, params object[] args) => Document.Diagnostics.Add(d, new TextSpan(offset, value.Length), args); }
void VisitPureLiteral(ValueInfo info, MSBuildValueKind kind, ExpressionLiteral node) { string value = node.GetUnescapedValue(); rr.ReferenceOffset = node.Offset; rr.ReferenceLength = node.Value.Length; rr.Reference = value; switch (kind) { case MSBuildValueKind.TaskOutputParameterName: rr.ReferenceKind = MSBuildReferenceKind.TaskParameter; return; case MSBuildValueKind.TargetName: rr.ReferenceKind = MSBuildReferenceKind.Target; return; case MSBuildValueKind.NuGetID: rr.ReferenceKind = MSBuildReferenceKind.NuGetID; return; case MSBuildValueKind.PropertyName: rr.ReferenceKind = MSBuildReferenceKind.Property; return; case MSBuildValueKind.ItemName: rr.ReferenceKind = MSBuildReferenceKind.Item; return; case MSBuildValueKind.TargetFramework: rr.ReferenceKind = MSBuildReferenceKind.TargetFramework; return; case MSBuildValueKind.TargetFrameworkIdentifier: rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkIdentifier; return; case MSBuildValueKind.TargetFrameworkVersion: rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkVersion; return; case MSBuildValueKind.TargetFrameworkProfile: rr.ReferenceKind = MSBuildReferenceKind.TargetFrameworkProfile; return; } IReadOnlyList <ConstantInfo> knownVals = info.Values ?? kind.GetSimpleValues(false); if (knownVals != null && knownVals.Count != 0) { foreach (var kv in knownVals) { if (string.Equals(kv.Name, value, StringComparison.OrdinalIgnoreCase)) { rr.ReferenceKind = MSBuildReferenceKind.KnownValue; return; } } } }