protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node) { //these are things like <Foo Include="@(Bar)" RemoveMetadata="SomeBarMetadata" /> if (kind.GetScalarType() == MSBuildValueKind.MetadataName) { var expr = GetIncludeExpression(element); if (expr != null && expr .WithAllDescendants() .OfType <ExpressionItemName> () .Any(n => IsItemNameMatch(n.ItemName)) ) { switch (node) { case ListExpression list: foreach (var c in list.Nodes) { if (c is ExpressionText l) { CheckMatch(l); break; } } break; case ExpressionText lit: CheckMatch(lit); break; } } void CheckMatch(ExpressionText t) { //FIXME: get rid of this trim if (t.IsPure && IsMatch(t.Value.Trim())) { Results.Add((t.Offset, t.Length, ReferenceUsage.Read)); } } return; } foreach (var n in node.WithAllDescendants()) { switch (n) { case ExpressionMetadata em: var iname = em.GetItemName(); if (iname != null && IsItemNameMatch(iname) && IsMatch(em.MetadataName)) { Results.Add((em.MetadataNameOffset, em.MetadataName.Length, ReferenceUsage.Read)); } break; } } }
protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node) { if (kind.GetScalarType() != MSBuildValueKind.TargetName) { return; } bool isDeclaration = !kind.AllowExpressions(); switch (node) { case ListExpression list: foreach (var c in list.Nodes) { if (c is ExpressionText l) { CheckMatch(l, isDeclaration); } } break; case ExpressionText lit: CheckMatch(lit, isDeclaration); break; } }
protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node) { if (kind.GetScalarType() != MSBuildValueKind.TargetName) { return; } switch (node) { case ExpressionList list: foreach (var c in list.Nodes) { if (c is ExpressionLiteral l) { CheckMatch(l); break; } } break; case ExpressionLiteral lit: CheckMatch(lit); break; } }
void ExtractReferences(MSBuildValueKind kind, string value, int startOffset) { try { var expression = ExpressionParser.Parse(value, ExpressionOptions.ItemsMetadataAndLists, startOffset); foreach (var node in expression.WithAllDescendants()) { switch (node) { case ExpressionPropertyName prop: CollectProperty(prop.Name); break; case ExpressionItemName item: CollectItem(item.Name); break; case ExpressionMetadata meta: var itemName = meta.GetItemName(); if (itemName != null) { CollectMetadata(itemName, meta.MetadataName); } break; case ExpressionText literal: if (literal.IsPure) { value = literal.GetUnescapedValue().Trim(); switch (kind.GetScalarType()) { case MSBuildValueKind.ItemName: CollectItem(value); break; case MSBuildValueKind.TargetName: CollectTarget(value); break; case MSBuildValueKind.PropertyName: CollectProperty(value); break; case MSBuildValueKind.Configuration: Document.Configurations.Add(value); break; case MSBuildValueKind.Platform: Document.Platforms.Add(value); break; } } break; } } } catch (Exception ex) { LoggingService.LogError($"Error parsing MSBuild expression '{value}' in file {Filename} at {startOffset}", ex); } }
protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute, ITypedSymbol valueType, MSBuildValueKind kind, ExpressionNode node) { switch (kind.GetScalarType()) { case MSBuildValueKind.TargetName: foreach (var n in node.WithAllDescendants()) { if (n is ExpressionText lit && lit.IsPure) { Navigations.Add(new MSBuildNavigationResult( MSBuildReferenceKind.Target, lit.Value, lit.Offset, lit.Length )); } } break; case MSBuildValueKind.File: case MSBuildValueKind.FileOrFolder: case MSBuildValueKind.ProjectFile: case MSBuildValueKind.TaskAssemblyFile: case MSBuildValueKind.Unknown: if (node is ListExpression list) { foreach (var n in list.Nodes) { var p = GetPathFromNode(n, (MSBuildRootDocument)Document); if (p != null) { Navigations.Add(p); } } } var path = GetPathFromNode(node, (MSBuildRootDocument)Document); if (path != null) { Navigations.Add(path); } break; } }
protected VariableInfo( string name, DisplayText description, MSBuildValueKind valueKind = MSBuildValueKind.Unknown, CustomTypeInfo customType = null, string defaultValue = null, bool isDeprecated = false, string deprecationMessage = null) : base(name, description) { if (valueKind.IsCustomType() && customType == null) { throw new ArgumentException($"When {nameof(valueKind)} is {nameof(MSBuildValueKind.CustomType)}, {nameof (customType)} cannot be null"); } // HACK: NuGetID stores PackageType on the CustomType if (customType != null && !(valueKind.IsCustomType() || valueKind.GetScalarType() == MSBuildValueKind.NuGetID)) { throw new ArgumentException($"When {nameof(customType)} is provided, {nameof(valueKind)} must be {nameof(MSBuildValueKind.CustomType)}"); } CustomType = customType; DefaultValue = defaultValue; IsDeprecated = isDeprecated || !string.IsNullOrEmpty(deprecationMessage); DeprecationMessage = deprecationMessage; ValueKind = valueKind; }
static string FormatKind(MSBuildValueKind kind) { switch (kind.GetScalarType()) { case MSBuildValueKind.Bool: return("bool"); case MSBuildValueKind.Int: return("int"); case MSBuildValueKind.String: return("string"); case MSBuildValueKind.Guid: return("guid"); case MSBuildValueKind.Url: return("url"); case MSBuildValueKind.Version: return("version"); case MSBuildValueKind.SuffixedVersion: return("version-suffixed"); case MSBuildValueKind.Lcid: return("lcid"); case MSBuildValueKind.DateTime: return("datetime"); case MSBuildValueKind.Char: return("char"); case MSBuildValueKind.Object: return("object"); case MSBuildValueKind.Float: return("float"); case MSBuildValueKind.TargetName: return("target-name"); case MSBuildValueKind.ItemName: return("item-name"); case MSBuildValueKind.PropertyName: return("property-name"); case MSBuildValueKind.MetadataName: return("metadata-name"); case MSBuildValueKind.TaskName: return("type-name"); case MSBuildValueKind.TaskAssemblyName: return("assembly-name"); case MSBuildValueKind.TaskAssemblyFile: return("file-path"); case MSBuildValueKind.TaskFactory: case MSBuildValueKind.TaskArchitecture: case MSBuildValueKind.TaskRuntime: return("enum"); case MSBuildValueKind.TaskOutputParameterName: return(null); case MSBuildValueKind.TaskParameterType: return("type-name"); case MSBuildValueKind.Sdk: return("sdk-id"); case MSBuildValueKind.SdkVersion: return("sdk-version"); case MSBuildValueKind.SdkWithVersion: return("sdk-id-version"); case MSBuildValueKind.Xmlns: case MSBuildValueKind.Label: return(null); case MSBuildValueKind.ToolsVersion: case MSBuildValueKind.Importance: case MSBuildValueKind.ContinueOnError: case MSBuildValueKind.HostOS: case MSBuildValueKind.HostRuntime: return("enum"); case MSBuildValueKind.Configuration: return("configuration"); case MSBuildValueKind.Platform: return("platform"); case MSBuildValueKind.RuntimeID: return("rid"); case MSBuildValueKind.TargetFramework: return("framework"); case MSBuildValueKind.TargetFrameworkIdentifier: return("framework-id"); case MSBuildValueKind.TargetFrameworkVersion: return("framework-version"); case MSBuildValueKind.TargetFrameworkProfile: return("framework-profile"); case MSBuildValueKind.TargetFrameworkMoniker: return("framework-moniker"); case MSBuildValueKind.ProjectFile: return("file-path"); case MSBuildValueKind.File: return("file-path"); case MSBuildValueKind.Folder: return("directory-path"); case MSBuildValueKind.FolderWithSlash: return("directory-path-trailing-slash"); case MSBuildValueKind.FileOrFolder: return("file-or-folder"); case MSBuildValueKind.Extension: return("file-extension"); case MSBuildValueKind.Filename: return("file-name"); case MSBuildValueKind.MatchItem: case MSBuildValueKind.UnknownItem: return("item"); case MSBuildValueKind.NuGetID: return("nuget-id"); case MSBuildValueKind.NuGetVersion: return("nuget-version"); case MSBuildValueKind.ProjectKindGuid: return("flavor-guid"); } return(null); }
protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute, ITypedSymbol valueDescriptor, MSBuildValueKind inferredKind, ExpressionNode node) { var nodeAtOffset = node.Find(offset); switch (nodeAtOffset) { case ExpressionItemName ei: rr.ReferenceKind = MSBuildReferenceKind.Item; rr.ReferenceOffset = ei.Offset; rr.ReferenceLength = ei.Name.Length; rr.Reference = ei.Name; break; case ExpressionPropertyName propName: rr.ReferenceKind = MSBuildReferenceKind.Property; rr.ReferenceOffset = propName.Offset; rr.Reference = propName.Name; rr.ReferenceLength = propName.Length; break; case ExpressionMetadata em: if (em.ItemName == null || offset >= em.MetadataNameOffset) { rr.ReferenceKind = MSBuildReferenceKind.Metadata; rr.ReferenceOffset = em.MetadataNameOffset; rr.Reference = (em.GetItemName(), em.MetadataName); rr.ReferenceLength = em.MetadataName.Length; } else { rr.ReferenceKind = MSBuildReferenceKind.Item; rr.ReferenceOffset = em.ItemNameOffset; rr.Reference = em.ItemName; rr.ReferenceLength = em.ItemName.Length; } break; case ExpressionFunctionName name: rr.ReferenceOffset = name.Offset; rr.ReferenceLength = name.Name.Length; switch (name.Parent) { case ExpressionItemNode _: rr.ReferenceKind = MSBuildReferenceKind.ItemFunction; rr.Reference = name.Name; break; case ExpressionPropertyFunctionInvocation prop: { if (prop.Target is ExpressionClassReference classRef) { rr.ReferenceKind = MSBuildReferenceKind.StaticPropertyFunction; rr.Reference = (classRef.Name, name.Name); } else if (prop.Target is ExpressionPropertyNode propNode) { var type = functionTypeProvider?.ResolveType(propNode) ?? MSBuildValueKind.Unknown; rr.ReferenceKind = MSBuildReferenceKind.PropertyFunction; rr.Reference = (type, name.Name); } break; } case ExpressionConditionFunction _: rr.ReferenceKind = MSBuildReferenceKind.ConditionFunction; rr.Reference = name.Name; break; } break; case ExpressionClassReference cr: if (!string.IsNullOrEmpty(cr.Name)) { if (cr.Parent is ExpressionArgumentList) { rr.ReferenceKind = MSBuildReferenceKind.Enum; } else if (cr.Parent is ExpressionPropertyFunctionInvocation) { rr.ReferenceKind = MSBuildReferenceKind.ClassName; } else { break; } rr.ReferenceOffset = cr.Offset; rr.Reference = cr.Name; rr.ReferenceLength = cr.Length; } break; case ExpressionText lit: inferredKind = inferredKind.GetScalarType(); if (lit.IsPure) { VisitPureLiteral(element, valueDescriptor, inferredKind, lit); if (inferredKind == MSBuildValueKind.TaskOutputParameterName) { rr.ReferenceKind = MSBuildReferenceKind.TaskParameter; rr.ReferenceOffset = lit.Offset; rr.ReferenceLength = lit.Value.Length; rr.Reference = (element.ParentElement.Name.Name, lit.Value); break; } } switch (inferredKind) { case MSBuildValueKind.File: case MSBuildValueKind.FileOrFolder: case MSBuildValueKind.ProjectFile: case MSBuildValueKind.TaskAssemblyFile: var pathNode = lit.Parent as ConcatExpression ?? (ExpressionNode)lit; var path = MSBuildNavigation.GetPathFromNode(pathNode, (MSBuildRootDocument)Document); if (path != null) { rr.ReferenceKind = MSBuildReferenceKind.FileOrFolder; rr.ReferenceOffset = path.Offset; rr.ReferenceLength = path.Length; rr.Reference = path.Paths; } break; } break; } }
public static bool IsCustomType(this MSBuildValueKind value) => value.GetScalarType() == MSBuildValueKind.CustomType;
protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node) { switch (node.Find(offset)) { case ExpressionItem ei: rr.ReferenceKind = MSBuildReferenceKind.Item; rr.ReferenceOffset = ei.NameOffset; rr.ReferenceLength = ei.Name.Length; rr.Reference = ei.Name; break; case ExpressionProperty ep: rr.ReferenceKind = MSBuildReferenceKind.Property; rr.ReferenceOffset = ep.NameOffset; rr.Reference = ep.Name; rr.ReferenceLength = ep.Name.Length; break; case ExpressionMetadata em: if (em.ItemName == null || offset >= em.MetadataNameOffset) { rr.ReferenceKind = MSBuildReferenceKind.Metadata; rr.ReferenceOffset = em.MetadataNameOffset; rr.Reference = (em.GetItemName(), em.MetadataName); rr.ReferenceLength = em.MetadataName.Length; } else { rr.ReferenceKind = MSBuildReferenceKind.Item; rr.ReferenceOffset = em.ItemNameOffset; rr.Reference = em.ItemName; rr.ReferenceLength = em.ItemName.Length; } break; case ExpressionLiteral lit: kind = kind.GetScalarType(); if (lit.IsPure) { VisitPureLiteral(info, kind, lit); if (kind == MSBuildValueKind.TaskOutputParameterName) { rr.ReferenceKind = MSBuildReferenceKind.TaskParameter; rr.ReferenceOffset = lit.Offset; rr.ReferenceLength = lit.Value.Length; rr.Reference = (element.ParentElement().Name.Name, lit.Value); break; } } switch (kind) { case MSBuildValueKind.File: case MSBuildValueKind.FileOrFolder: case MSBuildValueKind.ProjectFile: case MSBuildValueKind.TaskAssemblyFile: var pathNode = lit.Parent as Expression ?? (ExpressionNode)lit; var path = MSBuildNavigation.GetPathFromNode(pathNode, (MSBuildRootDocument)Document); if (path != null) { rr.ReferenceKind = MSBuildReferenceKind.FileOrFolder; rr.ReferenceOffset = path.Offset; rr.ReferenceLength = path.Length; rr.Reference = path.Paths; } break; } break; } }
protected override void VisitValueExpression( XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node) { switch (node.Find(offset)) { case ExpressionItemName ei: rr.ReferenceKind = MSBuildReferenceKind.Item; rr.ReferenceOffset = ei.Offset; rr.ReferenceLength = ei.Name.Length; rr.Reference = ei.Name; break; case ExpressionPropertyName propName: rr.ReferenceKind = MSBuildReferenceKind.Property; rr.ReferenceOffset = propName.Offset; rr.Reference = propName.Name; rr.ReferenceLength = propName.Length; break; case ExpressionMetadata em: if (em.ItemName == null || offset >= em.MetadataNameOffset) { rr.ReferenceKind = MSBuildReferenceKind.Metadata; rr.ReferenceOffset = em.MetadataNameOffset; rr.Reference = (em.GetItemName(), em.MetadataName); rr.ReferenceLength = em.MetadataName.Length; } else { rr.ReferenceKind = MSBuildReferenceKind.Item; rr.ReferenceOffset = em.ItemNameOffset; rr.Reference = em.ItemName; rr.ReferenceLength = em.ItemName.Length; } break; case ExpressionFunctionName name: rr.ReferenceOffset = name.Offset; rr.ReferenceLength = name.Name.Length; if (name.Parent is ExpressionItemNode item) { rr.ReferenceKind = MSBuildReferenceKind.ItemFunction; rr.Reference = name.Name; } else if (name.Parent is ExpressionPropertyFunctionInvocation prop) { if (prop.Target is ExpressionClassReference classRef) { rr.ReferenceKind = MSBuildReferenceKind.StaticPropertyFunction; rr.Reference = (classRef.Name, name.Name); } else { var type = FunctionCompletion.ResolveType(prop.Target); rr.ReferenceKind = MSBuildReferenceKind.PropertyFunction; rr.Reference = (type, name.Name); } } break; case ExpressionClassReference cr: if (!string.IsNullOrEmpty(cr.Name)) { if (cr.Parent is ExpressionArgumentList) { rr.ReferenceKind = MSBuildReferenceKind.Enum; } else if (cr.Parent is ExpressionPropertyFunctionInvocation) { rr.ReferenceKind = MSBuildReferenceKind.ClassName; } else { break; } rr.ReferenceOffset = cr.Offset; rr.Reference = cr.Name; rr.ReferenceLength = cr.Length; } break; case ExpressionText lit: kind = kind.GetScalarType(); if (lit.IsPure) { VisitPureLiteral(info, kind, lit); if (kind == MSBuildValueKind.TaskOutputParameterName) { rr.ReferenceKind = MSBuildReferenceKind.TaskParameter; rr.ReferenceOffset = lit.Offset; rr.ReferenceLength = lit.Value.Length; rr.Reference = (element.ParentElement().Name.Name, lit.Value); break; } } switch (kind) { case MSBuildValueKind.File: case MSBuildValueKind.FileOrFolder: case MSBuildValueKind.ProjectFile: case MSBuildValueKind.TaskAssemblyFile: var pathNode = lit.Parent as Expression ?? (ExpressionNode)lit; var path = MSBuildNavigation.GetPathFromNode(pathNode, (MSBuildRootDocument)Document); if (path != null) { rr.ReferenceKind = MSBuildReferenceKind.FileOrFolder; rr.ReferenceOffset = path.Offset; rr.ReferenceLength = path.Length; rr.Reference = path.Paths; } break; } break; } }