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;
                }
            }
示例#2
0
 public FunctionInfo(string name, DisplayText description, MSBuildValueKind returnType, params FunctionParameterInfo [] arguments) : base(name, description)
 {
     this.arguments  = arguments;
     this.ReturnType = returnType;
 }
 public TaskParameterInfo(string name, DisplayText description, bool isRequired, bool isOutput, MSBuildValueKind kind) : base(name, description, kind)
 {
     IsOutput   = isOutput;
     IsRequired = isRequired;
 }
 static void AddMetadata(string name, string description, MSBuildValueKind kind = MSBuildValueKind.Unknown, bool notReserved = false)
 {
     Metadata.Add(name, new MetadataInfo(name, description, !notReserved, false, kind));
 }
 protected virtual void VisitValueExpression(
     XElement element, XAttribute attribute,
     MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
     ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
 {
 }
示例#6
0
 public static MSBuildValueKind Literal(this MSBuildValueKind value)
 {
     return(value | MSBuildValueKind.Literal);
 }
            protected override void VisitValueExpression(XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
            {
                switch (kind.GetScalarType())
                {
                case MSBuildValueKind.TargetName:
                    foreach (var n in node.WithAllDescendants())
                    {
                        if (n is ExpressionLiteral 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 ExpressionList 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;
                }
            }
示例#8
0
        static MSBuildElementSyntax AddBuiltin(string name, string description, MSBuildSyntaxKind kind, MSBuildValueKind valueKind = MSBuildValueKind.Nothing, bool isAbstract = false)
        {
            var el = new MSBuildElementSyntax(name, description, kind, valueKind, isAbstract);

            builtin.Add(el.Name, el);
            return(el);
        }
        protected override void VisitValueExpression(
            XElement element, XAttribute attribute,
            MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
            ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
        {
            bool allowExpressions = kind.AllowExpressions();
            bool allowLists       = kind.AllowListsOrCommaLists();

            if (node is ListExpression list)
            {
                if (!allowLists)
                {
                    Document.Diagnostics.Add(
                        CoreDiagnostics.UnexpectedList,
                        new TextSpan(list.Nodes[0].End, list.End - list.Nodes[0].End),
                        ImmutableDictionary <string, object> .Empty.Add("Name", info.Name),
                        DescriptionFormatter.GetKindNoun(info),
                        info.Name);
                }
                if (!allowExpressions)
                {
                    var expr = list.Nodes.FirstOrDefault(n => !(n is ExpressionText));
                    if (expr != null)
                    {
                        AddExpressionWarning(expr);
                    }
                }
            }
            else if (node is ExpressionText lit)
            {
                VisitPureLiteral(info, kind, lit.GetUnescapedValue(), lit.Offset);
            }
            else
            {
                if (!allowExpressions)
                {
                    AddExpressionWarning(node);
                }
            }

            foreach (var n in node.WithAllDescendants())
            {
                switch (n)
                {
                case ExpressionError err:
                    var(desc, args) = CoreDiagnostics.GetExpressionError(err, info);
                    Document.Diagnostics.Add(desc, new TextSpan(err.Offset, Math.Max(1, err.Length)), args);
                    break;

                case ExpressionMetadata meta:
                    var metaItem = meta.GetItemName();
                    if (!string.IsNullOrEmpty(metaItem) && !IsMetadataUsed(metaItem, meta.MetadataName, ReferenceUsage.Write))
                    {
                        Document.Diagnostics.Add(
                            CoreDiagnostics.UnwrittenMetadata,
                            meta.Span,
                            ImmutableDictionary <string, object> .Empty
                            .Add("ItemName", metaItem)
                            .Add("Name", meta.MetadataName)
                            .Add("Spans", new [] { new TextSpan(meta.MetadataNameOffset, meta.MetadataName.Length) }),
                            metaItem, meta.MetadataName
                            );
                    }
                    break;

                case ExpressionPropertyName prop:
                    if (!IsPropertyUsed(prop.Name, ReferenceUsage.Write))
                    {
                        Document.Diagnostics.Add(
                            CoreDiagnostics.UnwrittenProperty,
                            prop.Span,
                            ImmutableDictionary <string, object> .Empty
                            .Add("Name", prop.Name)
                            .Add("Spans", new[] { new TextSpan(prop.Offset, prop.Length) }),
                            prop.Name
                            );
                    }
                    break;

                case ExpressionItemName item:
                    if (!IsItemUsed(item.Name, ReferenceUsage.Write))
                    {
                        Document.Diagnostics.Add(
                            CoreDiagnostics.UnwrittenItem,
                            item.Span,
                            ImmutableDictionary <string, object> .Empty
                            .Add("Name", item.Name)
                            .Add("Spans", new[] { new TextSpan(item.Offset, item.Length) }),
                            item.Name
                            );
                    }
                    //TODO: deprecation squiggles in expressions
                    break;
                }
            }

            void AddExpressionWarning(ExpressionNode n)
            => Document.Diagnostics.Add(CoreDiagnostics.UnexpectedExpression,
                                        new TextSpan(n.Offset, n.Length),
                                        DescriptionFormatter.GetKindNoun(info),
                                        info.Name);
        }
示例#10
0
 MSBuildLanguageElement(string name, string description, MSBuildKind kind, MSBuildValueKind valueKind = MSBuildValueKind.Nothing, bool isAbstract = false)
     : base(name, description, valueKind)
 {
     Kind       = kind;
     IsAbstract = isAbstract;
 }
示例#11
0
        void AddMetadata(ItemInfo item, JObject metaObj)
        {
            foreach (var kv in metaObj)
            {
                var name = kv.Key;

                //simple version, just a description string
                if (kv.Value is JValue value)
                {
                    var desc      = ((string)value.Value).Trim();
                    var reference = GetMetadataReference(desc, item);
                    if (reference != null)
                    {
                        item.Metadata.Add(name, WithNewName(reference, name, item));
                    }
                    else
                    {
                        item.Metadata.Add(name, new MetadataInfo(name, desc));
                    }
                    continue;
                }

                string              description = null, valueSeparators = null, defaultValue = null;
                bool                required = false;
                MSBuildValueKind    kind     = MSBuildValueKind.Unknown;
                List <ConstantInfo> values   = null;
                foreach (var mkv in (JObject)kv.Value)
                {
                    switch (mkv.Key)
                    {
                    case "description":
                        description = (string)((JValue)mkv.Value).Value;
                        break;

                    case "kind":
                        kind = ParseValueKind((string)((JValue)mkv.Value).Value);
                        break;

                    case "values":
                        switch (mkv.Value)
                        {
                        case JValue jv:
                            var metaRef = GetMetadataReference((string)jv.Value, item);
                            if (metaRef == null)
                            {
                                throw new Exception("Invalid metadata reference");
                            }
                            values = metaRef.Values;
                            break;

                        case JObject jo:
                            values = GetValues(jo);
                            break;
                        }
                        break;

                    case "valueSeparators":
                        valueSeparators = (string)((JValue)mkv.Value).Value;
                        break;

                    case "default":
                        defaultValue = (string)((JValue)mkv.Value).Value;
                        break;

                    case "required":
                        required = (bool)((JValue)mkv.Value).Value;
                        break;

                    default:
                        throw new Exception($"Unknown property {mkv.Key} in metadata {kv.Key}");
                    }
                }

                kind = CheckKind(kind, valueSeparators, values);

                item.Metadata.Add(
                    name,
                    new MetadataInfo(
                        name, description, false, required, kind, item,
                        values, defaultValue
                        )
                    );
            }
        }
            void VisitPureLiteral(XElement element, ValueInfo info, MSBuildValueKind kind, ExpressionText 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.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;
                }

                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;
                            rr.Reference     = kv;
                            return;
                        }
                    }
                }
            }
            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 = functionTypeProvider?.ResolveType(prop.Target) ?? MSBuildValueKind.Unknown;
                            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(element, 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 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;
                }
            }
            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;
                        }
                    }
                }
            }
示例#15
0
 public static bool AllowCommaLists(this MSBuildValueKind value)
 {
     return((value & MSBuildValueKind.CommaList) != 0 || value == MSBuildValueKind.Unknown);
 }
        //note: the value is unescaped, so offsets within it are not valid
        void VisitPureLiteral(ValueInfo info, MSBuildValueKind kind, string value, int offset)
        {
            if (info.CustomType != null && info.CustomType.AllowUnknownValues)
            {
                return;
            }

            var knownVals = (IReadOnlyList <BaseInfo>)info.CustomType?.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 AddErrorWithArgs(MSBuildDiagnosticDescriptor d, params object[] args) => Document.Diagnostics.Add(d, new TextSpan(offset, value.Length), args);
        }
示例#17
0
 public static MSBuildValueKind List(this MSBuildValueKind value)
 {
     return(value | MSBuildValueKind.List);
 }
        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 ExpressionProperty prop:
                        if (prop.IsSimpleProperty)
                        {
                            CollectProperty(prop.Name);
                        }
                        break;

                    case ExpressionItem 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);
            }
        }
示例#19
0
        //FIXME: cache these somewhere?
        public static IReadOnlyList <ConstantInfo> GetSimpleValues(this MSBuildValueKind kind, bool includeParseableTypes)
        {
            switch (kind)
            {
            case MSBuildValueKind.Bool:
                if (!includeParseableTypes)
                {
                    return(null);
                }
                return(new ConstantInfo [] {
                    new ConstantInfo("True", null),
                    new ConstantInfo("False", null),
                });

            case MSBuildValueKind.TaskArchitecture:
                return(new ConstantInfo [] {
                    new ConstantInfo("*", "Any architecture"),
                    new ConstantInfo("CurrentArchitecture", "The architecture on which MSBuild is running"),
                    new ConstantInfo("x86", "The 32-bit x86 architecture"),
                    new ConstantInfo("x64", "The 64-bit x64 architecture"),
                });

            case MSBuildValueKind.TaskRuntime:
                return(new ConstantInfo [] {
                    new ConstantInfo("*", "Any runtime"),
                    new ConstantInfo("CurrentRuntime", "The runtime on which MSBuild is running"),
                    new ConstantInfo("CLR2", "The .NET 2.0 runtime"),
                    new ConstantInfo("CLR4", "The .NET 4.0 runtime"),
                });

            case MSBuildValueKind.Importance:
                return(new ConstantInfo [] {
                    new ConstantInfo("high", "High importance, only displayed for all log verbosity settings"),
                    new ConstantInfo("normal", "Normal importance"),
                    new ConstantInfo("low", "Low importance, only displayed for highly verbose log settings")
                });

            case MSBuildValueKind.HostOS:
                return(new ConstantInfo [] {
                    new ConstantInfo("Windows_NT", "Running on Windows"),
                    new ConstantInfo("Unix", "Running on Unix")
                    // deliberately ignoring Mac as it doesn't actually work
                });

            case MSBuildValueKind.HostRuntime:
                return(new ConstantInfo [] {
                    new ConstantInfo("Mono", "Running on Mono"),
                    new ConstantInfo("Core", "Running on .NET Core"),
                    new ConstantInfo("Full", "Running on .NET Framework")
                });

            case MSBuildValueKind.ContinueOnError:
                return(new ConstantInfo [] {
                    new ConstantInfo("WarnAndContinue", "When the task outputs errors, convert them to warnings, and continue executing other tasks and targets"),
                    new ConstantInfo("true", "Equivalent to `WarnAndContinue`"),
                    new ConstantInfo("ErrorAndContinue", "When the task outputs errors, continue executing other tasks and targets"),
                    new ConstantInfo("ErrorAndStop", "When the task outputs errors, do not execute further tasks and targets"),
                    new ConstantInfo("true", "Equivalent to `ErrorAndStop`"),
                });

            case MSBuildValueKind.ToolsVersion:
                return(new ConstantInfo [] {
                    new ConstantInfo("2.0", "MSBuild 2.0, included in .NET Framework 2.0"),
                    new ConstantInfo("3.5", "MSBuild 3.5, included in .NET Framework 3.5"),
                    new ConstantInfo("4.0", "MSBuild 4.0, included in .NET Framework 4.0"),
                    new ConstantInfo("12.0", "MSBuild 12.0, included in Visual Studio 2013"),
                    new ConstantInfo("14.0", "MSBuild 14.0, included in Visual Studio 2015"),
                    new ConstantInfo("15.0", "MSBuild 15.0, included in Visual Studio 2017"),
                });
            }
            return(null);
        }
 //FIXME: make this lookup cheaper
 public FunctionInfo GetPropertyFunctionInfo(MSBuildValueKind valueKind, string name)
 {
     return(Find(GetInstanceFunctions(valueKind, true, true), name));
 }
 public MSBuildPropertyFunctionReferenceCollector(
     MSBuildValueKind valueKind, string functionName, IFunctionTypeProvider functionTypeProvider,
     Action <(int Offset, int Length, ReferenceUsage Usage)> reportResult)
示例#22
0
 public ValueKindValue(string name, DisplayText description, MSBuildValueKind kind) : base(name, description)
 {
     this.ValueKind = kind;
 }
 static void AddProperty(string name, string description, MSBuildValueKind kind = MSBuildValueKind.Unknown, bool notReserved = false)
 {
     Properties.Add(name, new PropertyInfo(name, description, !notReserved, kind));
 }
        public static IEnumerable <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 ValueKindValue(c, "", MSBuildValueKind.Configuration)).ToList());

            case MSBuildValueKind.Platform:
                return(doc.GetPlatforms().Select(c => new ValueKindValue(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);
        }
        static string FormatKind(ValueInfo info, MSBuildValueKind kind)
        {
            if (info.Values != null && info.Values.Count > 0)
            {
                return("enum");
            }
            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.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.UnknownItem:
                return("item");

            case MSBuildValueKind.NuGetID:
                return("nuget-id");

            case MSBuildValueKind.NuGetVersion:
                return("nuget-version");

            case MSBuildValueKind.ProjectKindGuid:
                return("flavor-guid");
            }
            return(null);
        }
示例#26
0
 public static MSBuildValueKind GetScalarType(this MSBuildValueKind value)
 {
     return(value & ~(MSBuildValueKind.List | MSBuildValueKind.Literal));
 }
示例#27
0
 public FunctionParameterInfo(string name, DisplayText description, MSBuildValueKind type) : base(name, description)
 {
     this.type = string.Join(" ", type.GetTypeDescription());
 }
示例#28
0
 public static bool AllowExpressions(this MSBuildValueKind value)
 {
     return((value & MSBuildValueKind.Literal) == 0);
 }
示例#29
0
        protected override void VisitValueExpression(
            XElement element, XAttribute attribute,
            MSBuildElementSyntax resolvedElement, MSBuildAttributeSyntax resolvedAttribute,
            ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
        {
            bool allowExpressions = kind.AllowExpressions();
            bool allowLists       = kind.AllowListsOrCommaLists();

            if (node is ListExpression list)
            {
                if (!allowLists)
                {
                    Document.Diagnostics.Add(
                        CoreDiagnostics.UnexpectedList,
                        new TextSpan(list.Nodes[0].End, list.End - list.Nodes[0].End),
                        ImmutableDictionary <string, object> .Empty.Add("Name", info.Name),
                        DescriptionFormatter.GetKindNoun(info),
                        info.Name);
                }
                if (!allowExpressions)
                {
                    var expr = list.Nodes.FirstOrDefault(n => !(n is ExpressionText));
                    if (expr != null)
                    {
                        AddExpressionWarning(expr);
                    }
                }
            }
            else if (node is ExpressionText lit)
            {
                VisitPureLiteral(info, kind, lit.GetUnescapedValue(), lit.Offset);
            }
            else
            {
                if (!allowExpressions)
                {
                    AddExpressionWarning(node);
                }
            }

            foreach (var n in node.WithAllDescendants())
            {
                switch (n)
                {
                case ExpressionError err:
                    var(desc, args) = CoreDiagnostics.GetExpressionError(err, info);
                    Document.Diagnostics.Add(desc, new TextSpan(err.Offset, Math.Max(1, err.Length)), args);
                    break;

                case ExpressionMetadata meta:
                case ExpressionProperty prop:
                case ExpressionItem item:
                    //TODO: can we validate property/metadata/items refs?
                    //maybe warn if they're not used anywhere outside of this expression?
                    //TODO: deprecation squiggles in expressions
                    break;
                }
            }

            void AddExpressionWarning(ExpressionNode n)
            => Document.Diagnostics.Add(CoreDiagnostics.UnexpectedExpression,
                                        new TextSpan(n.Offset, n.Length),
                                        DescriptionFormatter.GetKindNoun(info),
                                        info.Name);
        }
示例#30
0
        //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);
        }